@vercel/factory 0.0.3 → 0.0.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/approval-h5aj8HYN.d.mts +510 -0
- package/dist/blob/index.d.mts +32 -0
- package/dist/blob/index.mjs +141 -0
- package/dist/blob/index.mjs.map +1 -0
- package/dist/connectors/index.d.mts +2 -0
- package/dist/connectors/index.mjs +49 -0
- package/dist/connectors/index.mjs.map +1 -0
- package/dist/driver-Bbd25rNM.mjs +23 -0
- package/dist/driver-Bbd25rNM.mjs.map +1 -0
- package/dist/driver-CrZsy7sm.d.mts +34 -0
- package/dist/eve/index.d.mts +1057 -0
- package/dist/eve/index.mjs +777 -0
- package/dist/eve/index.mjs.map +1 -0
- package/dist/github-5qQPCaXj.d.mts +123 -0
- package/dist/github.d.mts +2 -0
- package/dist/github.mjs +286 -0
- package/dist/github.mjs.map +1 -0
- package/dist/id-DwCihQr4.mjs +31 -0
- package/dist/id-DwCihQr4.mjs.map +1 -0
- package/dist/index-WNGZJRRH.d.mts +67 -0
- package/dist/index.d.mts +175 -0
- package/dist/index.mjs +882 -0
- package/dist/index.mjs.map +1 -0
- package/dist/next-page.d.mts +5 -0
- package/dist/next-page.mjs +71 -0
- package/dist/next-page.mjs.map +1 -0
- package/dist/next.d.mts +12 -0
- package/dist/{next.js → next.mjs} +13 -14
- package/dist/next.mjs.map +1 -0
- package/dist/postgres/index.d.mts +137 -0
- package/dist/postgres/index.mjs +96 -0
- package/dist/postgres/index.mjs.map +1 -0
- package/dist/signal-CHVEmzvI.d.mts +59 -0
- package/dist/task-Cj7Ei9Nh.mjs +336 -0
- package/dist/task-Cj7Ei9Nh.mjs.map +1 -0
- package/package.json +25 -22
- package/dist/approval-Z7iaWibT.d.ts +0 -541
- package/dist/blob/index.d.ts +0 -26
- package/dist/blob/index.js +0 -127
- package/dist/blob/index.js.map +0 -1
- package/dist/chunk-2JFES6BA.js +0 -41
- package/dist/chunk-2JFES6BA.js.map +0 -1
- package/dist/chunk-CEF6VJZC.js +0 -28
- package/dist/chunk-CEF6VJZC.js.map +0 -1
- package/dist/chunk-D2XMABG4.js +0 -311
- package/dist/chunk-D2XMABG4.js.map +0 -1
- package/dist/chunk-EFL4PDDE.js +0 -325
- package/dist/chunk-EFL4PDDE.js.map +0 -1
- package/dist/common-CaHaEOAS.d.ts +0 -18
- package/dist/connectors/index.d.ts +0 -53
- package/dist/connectors/index.js +0 -64
- package/dist/connectors/index.js.map +0 -1
- package/dist/driver-tRNggCCJ.d.ts +0 -32
- package/dist/eve/index.d.ts +0 -1053
- package/dist/eve/index.js +0 -752
- package/dist/eve/index.js.map +0 -1
- package/dist/github.d.ts +0 -139
- package/dist/github.js +0 -27
- package/dist/github.js.map +0 -1
- package/dist/index.d.ts +0 -164
- package/dist/index.js +0 -940
- package/dist/index.js.map +0 -1
- package/dist/next-page.d.ts +0 -5
- package/dist/next-page.js +0 -75
- package/dist/next-page.js.map +0 -1
- package/dist/next.d.ts +0 -12
- package/dist/next.js.map +0 -1
- package/dist/postgres/index.d.ts +0 -137
- package/dist/postgres/index.js +0 -118
- package/dist/postgres/index.js.map +0 -1
package/dist/chunk-EFL4PDDE.js
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
changeIdSchema,
|
|
3
|
-
isoDateTimeSchema,
|
|
4
|
-
replyToSchema,
|
|
5
|
-
repositoryIdSchema,
|
|
6
|
-
repositoryIdsSchema,
|
|
7
|
-
schemaVersionSchema,
|
|
8
|
-
signalIdSchema,
|
|
9
|
-
taskIdSchema,
|
|
10
|
-
usdSchema,
|
|
11
|
-
vocabularySchema
|
|
12
|
-
} from "./chunk-2JFES6BA.js";
|
|
13
|
-
import {
|
|
14
|
-
RecordNotFoundError
|
|
15
|
-
} from "./chunk-CEF6VJZC.js";
|
|
16
|
-
|
|
17
|
-
// src/schema/finding.ts
|
|
18
|
-
import { createHash } from "crypto";
|
|
19
|
-
import { z } from "zod";
|
|
20
|
-
var findingPrioritySchema = z.enum(["P0", "P1", "P2", "P3"]).describe("Urgency of a finding: P0 is drop-everything, P3 is nice-to-have.");
|
|
21
|
-
var findingCategorySchema = z.enum([
|
|
22
|
-
"security",
|
|
23
|
-
"correctness",
|
|
24
|
-
"reliability",
|
|
25
|
-
"performance",
|
|
26
|
-
"compatibility",
|
|
27
|
-
"accessibility",
|
|
28
|
-
"documentation",
|
|
29
|
-
"maintainability",
|
|
30
|
-
"testing",
|
|
31
|
-
"usability"
|
|
32
|
-
]);
|
|
33
|
-
var findingVerificationLevelSchema = z.enum(["unverified", "supported", "confirmed"]).describe(
|
|
34
|
-
"How sure the reporter is: unverified = suspected from reading; supported = evidence points to it; confirmed = demonstrated."
|
|
35
|
-
);
|
|
36
|
-
var findingVerificationMethodSchema = z.enum([
|
|
37
|
-
"code_inspection",
|
|
38
|
-
"static_analysis",
|
|
39
|
-
"manual_reproduction",
|
|
40
|
-
"unit_test",
|
|
41
|
-
"integration_test",
|
|
42
|
-
"e2e_test",
|
|
43
|
-
"runtime_observation",
|
|
44
|
-
"documentation"
|
|
45
|
-
]);
|
|
46
|
-
var findingVerificationSchema = z.strictObject({
|
|
47
|
-
level: findingVerificationLevelSchema,
|
|
48
|
-
method: findingVerificationMethodSchema,
|
|
49
|
-
summary: z.string().min(1).max(2e3).describe("What was checked and what it showed."),
|
|
50
|
-
limitations: z.string().min(1).max(2e3).optional().describe("What could not be checked.")
|
|
51
|
-
});
|
|
52
|
-
var findingSchema = z.strictObject({
|
|
53
|
-
title: z.string().min(1).max(200),
|
|
54
|
-
body: z.string().min(1).max(8e3).describe("The problem, its impact, and how to fix it. Markdown."),
|
|
55
|
-
path: z.string().min(1).max(500).optional().describe("Repository-relative file path."),
|
|
56
|
-
line: z.number().int().min(1).optional(),
|
|
57
|
-
endLine: z.number().int().min(1).optional(),
|
|
58
|
-
priority: findingPrioritySchema,
|
|
59
|
-
category: findingCategorySchema,
|
|
60
|
-
verification: findingVerificationSchema,
|
|
61
|
-
tool: z.string().min(1).max(100).optional().describe("Scanner that produced it, e.g. deepsec."),
|
|
62
|
-
ruleId: z.string().min(1).max(200).optional().describe("Scanner rule or check id, when there is one.")
|
|
63
|
-
});
|
|
64
|
-
function findingFingerprint(repositoryId, finding) {
|
|
65
|
-
const parts = finding.tool !== void 0 && finding.ruleId !== void 0 && finding.path !== void 0 ? [repositoryId, finding.tool, finding.ruleId, finding.path] : [
|
|
66
|
-
repositoryId,
|
|
67
|
-
finding.tool ?? "",
|
|
68
|
-
finding.ruleId ?? "",
|
|
69
|
-
finding.path ?? "",
|
|
70
|
-
finding.title.trim().toLowerCase().replaceAll(/\s+/gu, " ")
|
|
71
|
-
];
|
|
72
|
-
return createHash("sha256").update(parts.join(" ")).digest("hex").slice(0, 32);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// src/approval.ts
|
|
76
|
-
import { z as z2 } from "zod";
|
|
77
|
-
var approvalRuleSchema = z2.strictObject({
|
|
78
|
-
source: vocabularySchema.optional().describe("Signal source, e.g. security_scan or github_issue."),
|
|
79
|
-
kind: vocabularySchema.optional().describe("Task kind, e.g. code_change."),
|
|
80
|
-
priority: z2.array(findingPrioritySchema).min(1).optional().describe("Finding priorities the rule applies to."),
|
|
81
|
-
require: z2.boolean().describe("Whether matching tasks wait for a human before dispatch.")
|
|
82
|
-
});
|
|
83
|
-
var approvalPolicySchema = z2.array(approvalRuleSchema).describe("First-match rules deciding which tasks need a human before they run.");
|
|
84
|
-
var defaultApprovalPolicy = [
|
|
85
|
-
{ kind: "verification", require: false },
|
|
86
|
-
{ source: "security_scan", require: true },
|
|
87
|
-
{ require: false }
|
|
88
|
-
];
|
|
89
|
-
function requiresApproval(policy, subject) {
|
|
90
|
-
for (const rule of policy) {
|
|
91
|
-
if (rule.source !== void 0 && rule.source !== subject.source) continue;
|
|
92
|
-
if (rule.kind !== void 0 && rule.kind !== subject.kind) continue;
|
|
93
|
-
if (rule.priority !== void 0) {
|
|
94
|
-
if (subject.priority === void 0 || !rule.priority.includes(subject.priority)) continue;
|
|
95
|
-
}
|
|
96
|
-
return rule.require;
|
|
97
|
-
}
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// src/dispatch.ts
|
|
102
|
-
var DispatchRefusedError = class extends Error {
|
|
103
|
-
taskId;
|
|
104
|
-
reason;
|
|
105
|
-
constructor(taskId, reason) {
|
|
106
|
-
super(`dispatch of "${taskId}" refused: ${reason}`);
|
|
107
|
-
this.name = "DispatchRefusedError";
|
|
108
|
-
this.taskId = taskId;
|
|
109
|
-
this.reason = reason;
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
async function dispatchTask(stores, taskId, options) {
|
|
113
|
-
const task = await stores.tasks.get(taskId);
|
|
114
|
-
if (task === null) {
|
|
115
|
-
throw new RecordNotFoundError("tasks", taskId);
|
|
116
|
-
}
|
|
117
|
-
if (task.kind === "question") {
|
|
118
|
-
throw new DispatchRefusedError(taskId, "question tasks are answered, not dispatched");
|
|
119
|
-
}
|
|
120
|
-
if (task.approval === "required") {
|
|
121
|
-
throw new DispatchRefusedError(taskId, "awaiting human approval");
|
|
122
|
-
}
|
|
123
|
-
if (task.approval === "denied") {
|
|
124
|
-
throw new DispatchRefusedError(taskId, "approval was denied");
|
|
125
|
-
}
|
|
126
|
-
for (const dependencyId of task.dependsOn ?? []) {
|
|
127
|
-
const dependency = await stores.tasks.get(dependencyId);
|
|
128
|
-
if (dependency === null) {
|
|
129
|
-
throw new DispatchRefusedError(taskId, `dependency "${dependencyId}" does not exist`);
|
|
130
|
-
}
|
|
131
|
-
if (dependency.changeId === void 0) {
|
|
132
|
-
throw new DispatchRefusedError(
|
|
133
|
-
taskId,
|
|
134
|
-
`dependency "${dependencyId}" has not produced a change`
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
const running = await stores.tasks.transition(taskId, "running");
|
|
139
|
-
try {
|
|
140
|
-
await options.launch(running);
|
|
141
|
-
} catch (error) {
|
|
142
|
-
const reason = (error instanceof Error ? error.message : String(error)).slice(0, 500);
|
|
143
|
-
await stores.tasks.transition(taskId, "failed", { reason: `launch failed: ${reason}` }).catch(() => void 0);
|
|
144
|
-
throw error;
|
|
145
|
-
}
|
|
146
|
-
return running;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// src/schema/change.ts
|
|
150
|
-
import { z as z3 } from "zod";
|
|
151
|
-
var levelSchema = z3.enum(["low", "medium", "high"]);
|
|
152
|
-
var changeStateSchema = z3.enum([
|
|
153
|
-
"verifying",
|
|
154
|
-
"ready",
|
|
155
|
-
"merged",
|
|
156
|
-
"deployed",
|
|
157
|
-
"rolled_out",
|
|
158
|
-
"rolled_back",
|
|
159
|
-
"closed"
|
|
160
|
-
]);
|
|
161
|
-
var postMergeStates = ["merged", "deployed", "rolled_out", "rolled_back"];
|
|
162
|
-
var changeEvidenceSchema = z3.strictObject({
|
|
163
|
-
reproVerified: z3.boolean(),
|
|
164
|
-
testsAdded: z3.number().int().min(0),
|
|
165
|
-
checksGreen: z3.boolean(),
|
|
166
|
-
attackPassed: z3.boolean(),
|
|
167
|
-
scopeMatches: z3.boolean(),
|
|
168
|
-
previewUrl: z3.url().optional()
|
|
169
|
-
});
|
|
170
|
-
var changeSchema = z3.strictObject({
|
|
171
|
-
schemaVersion: schemaVersionSchema,
|
|
172
|
-
id: changeIdSchema,
|
|
173
|
-
repositoryId: repositoryIdSchema,
|
|
174
|
-
taskId: taskIdSchema.optional(),
|
|
175
|
-
groupId: taskIdSchema.optional(),
|
|
176
|
-
prNumber: z3.number().int().min(1),
|
|
177
|
-
prUrl: z3.url(),
|
|
178
|
-
author: z3.string().min(1),
|
|
179
|
-
risk: levelSchema,
|
|
180
|
-
confidence: levelSchema,
|
|
181
|
-
evidence: changeEvidenceSchema,
|
|
182
|
-
state: changeStateSchema,
|
|
183
|
-
decidedBy: z3.string().min(1).optional(),
|
|
184
|
-
createdAt: isoDateTimeSchema,
|
|
185
|
-
updatedAt: isoDateTimeSchema
|
|
186
|
-
}).superRefine((change, ctx) => {
|
|
187
|
-
if (postMergeStates.includes(change.state) && change.decidedBy === void 0) {
|
|
188
|
-
ctx.addIssue({
|
|
189
|
-
code: "custom",
|
|
190
|
-
path: ["decidedBy"],
|
|
191
|
-
message: `${change.state} changes require decidedBy`
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// src/schema/task.ts
|
|
197
|
-
import { z as z4 } from "zod";
|
|
198
|
-
var standardTaskKinds = [
|
|
199
|
-
"code_change",
|
|
200
|
-
"verification",
|
|
201
|
-
"investigation",
|
|
202
|
-
"question"
|
|
203
|
-
];
|
|
204
|
-
var taskKindSchema = vocabularySchema.describe(
|
|
205
|
-
"What kind of work this is, e.g. code_change, question, or a registered custom kind."
|
|
206
|
-
);
|
|
207
|
-
var taskStateSchema = z4.enum(["queued", "running", "verifying", "succeeded", "failed", "needs_human", "cancelled"]).describe("Lifecycle state. Transitions are fixed; see taskTransitions.");
|
|
208
|
-
var taskApprovalSchema = z4.enum(["required", "granted", "denied"]).describe(
|
|
209
|
-
"Human approval status. Absent means no approval is needed. Stamped required at creation by policy; granted or denied by an operator."
|
|
210
|
-
);
|
|
211
|
-
var harnessSchema = z4.string().min(1).describe("Coding harness used in the devbox, e.g. claude-code or codex.");
|
|
212
|
-
var taskOriginSchema = z4.strictObject({
|
|
213
|
-
signalId: signalIdSchema.optional().describe("Signal that led to this task."),
|
|
214
|
-
parentTaskId: taskIdSchema.optional().describe("Parent task that planned this child."),
|
|
215
|
-
operator: z4.string().min(1).optional().describe("Human operator who requested it.")
|
|
216
|
-
}).refine(
|
|
217
|
-
(origin) => origin.signalId !== void 0 || origin.parentTaskId !== void 0 || origin.operator !== void 0,
|
|
218
|
-
{ message: "origin requires a signalId, parentTaskId, or operator" }
|
|
219
|
-
);
|
|
220
|
-
var taskDevboxSchema = z4.strictObject({
|
|
221
|
-
devboxId: z4.string().min(1).describe("Devbox running or having run this task."),
|
|
222
|
-
remoteId: z4.string().min(1).describe("Provider-side id of the execution."),
|
|
223
|
-
harness: harnessSchema
|
|
224
|
-
});
|
|
225
|
-
var taskQuestionSchema = z4.strictObject({
|
|
226
|
-
text: z4.string().min(1).describe("The question a human must answer."),
|
|
227
|
-
options: z4.array(z4.string().min(1)).describe("Suggested answers; free-text is also allowed."),
|
|
228
|
-
answer: z4.string().min(1).optional(),
|
|
229
|
-
answeredBy: z4.string().min(1).optional().describe("Authenticated operator who answered.")
|
|
230
|
-
});
|
|
231
|
-
var taskSchema = z4.strictObject({
|
|
232
|
-
schemaVersion: schemaVersionSchema,
|
|
233
|
-
id: taskIdSchema,
|
|
234
|
-
repositoryIds: repositoryIdsSchema.optional().describe("Repositories the task works on; absent only on a multi-repo parent."),
|
|
235
|
-
kind: taskKindSchema,
|
|
236
|
-
area: z4.string().min(1).optional().describe("Investigation area, e.g. onboarding or security. Investigation tasks only."),
|
|
237
|
-
state: taskStateSchema,
|
|
238
|
-
approval: taskApprovalSchema.optional(),
|
|
239
|
-
origin: taskOriginSchema,
|
|
240
|
-
dependsOn: z4.array(taskIdSchema).min(1).optional().describe("Sibling tasks that must produce a change before this one may run."),
|
|
241
|
-
replyTo: replyToSchema,
|
|
242
|
-
devbox: taskDevboxSchema.optional(),
|
|
243
|
-
attempt: z4.number().int().min(1).describe("Execution attempt, starting at 1; bumps on retry."),
|
|
244
|
-
reservedUsd: usdSchema.optional().describe("Budget reserved before dispatch."),
|
|
245
|
-
settledUsd: usdSchema.optional().describe("Measured cost settled after execution."),
|
|
246
|
-
question: taskQuestionSchema.optional(),
|
|
247
|
-
changeId: changeIdSchema.optional().describe("Change this code_change task produced."),
|
|
248
|
-
reportRef: z4.string().min(1).optional().describe("Reference to the report artifact an investigation produced."),
|
|
249
|
-
createdAt: isoDateTimeSchema,
|
|
250
|
-
updatedAt: isoDateTimeSchema
|
|
251
|
-
}).superRefine((task, ctx) => {
|
|
252
|
-
if (task.area !== void 0 && task.kind !== "investigation") {
|
|
253
|
-
ctx.addIssue({
|
|
254
|
-
code: "custom",
|
|
255
|
-
path: ["area"],
|
|
256
|
-
message: "area is only valid on investigation tasks"
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
if (task.kind === "question") {
|
|
260
|
-
if (task.question === void 0) {
|
|
261
|
-
ctx.addIssue({
|
|
262
|
-
code: "custom",
|
|
263
|
-
path: ["question"],
|
|
264
|
-
message: "question tasks require a question"
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
if (task.devbox !== void 0) {
|
|
268
|
-
ctx.addIssue({
|
|
269
|
-
code: "custom",
|
|
270
|
-
path: ["devbox"],
|
|
271
|
-
message: "question tasks never run in a devbox"
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
} else if (task.question !== void 0) {
|
|
275
|
-
ctx.addIssue({
|
|
276
|
-
code: "custom",
|
|
277
|
-
path: ["question"],
|
|
278
|
-
message: "question is only valid on question tasks"
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
if (task.changeId !== void 0 && task.kind !== "code_change") {
|
|
282
|
-
ctx.addIssue({
|
|
283
|
-
code: "custom",
|
|
284
|
-
path: ["changeId"],
|
|
285
|
-
message: "changeId is only valid on code_change tasks"
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
if (task.reportRef !== void 0 && task.kind !== "investigation") {
|
|
289
|
-
ctx.addIssue({
|
|
290
|
-
code: "custom",
|
|
291
|
-
path: ["reportRef"],
|
|
292
|
-
message: "reportRef is only valid on investigation tasks"
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
export {
|
|
298
|
-
findingPrioritySchema,
|
|
299
|
-
findingCategorySchema,
|
|
300
|
-
findingVerificationLevelSchema,
|
|
301
|
-
findingVerificationMethodSchema,
|
|
302
|
-
findingVerificationSchema,
|
|
303
|
-
findingSchema,
|
|
304
|
-
findingFingerprint,
|
|
305
|
-
approvalRuleSchema,
|
|
306
|
-
approvalPolicySchema,
|
|
307
|
-
defaultApprovalPolicy,
|
|
308
|
-
requiresApproval,
|
|
309
|
-
DispatchRefusedError,
|
|
310
|
-
dispatchTask,
|
|
311
|
-
levelSchema,
|
|
312
|
-
changeStateSchema,
|
|
313
|
-
changeEvidenceSchema,
|
|
314
|
-
changeSchema,
|
|
315
|
-
standardTaskKinds,
|
|
316
|
-
taskKindSchema,
|
|
317
|
-
taskStateSchema,
|
|
318
|
-
taskApprovalSchema,
|
|
319
|
-
harnessSchema,
|
|
320
|
-
taskOriginSchema,
|
|
321
|
-
taskDevboxSchema,
|
|
322
|
-
taskQuestionSchema,
|
|
323
|
-
taskSchema
|
|
324
|
-
};
|
|
325
|
-
//# sourceMappingURL=chunk-EFL4PDDE.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schema/finding.ts","../src/approval.ts","../src/dispatch.ts","../src/schema/change.ts","../src/schema/task.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\n\nexport const findingPrioritySchema = z\n .enum([\"P0\", \"P1\", \"P2\", \"P3\"])\n .describe(\"Urgency of a finding: P0 is drop-everything, P3 is nice-to-have.\");\n\nexport const findingCategorySchema = z.enum([\n \"security\",\n \"correctness\",\n \"reliability\",\n \"performance\",\n \"compatibility\",\n \"accessibility\",\n \"documentation\",\n \"maintainability\",\n \"testing\",\n \"usability\",\n]);\n\nexport const findingVerificationLevelSchema = z\n .enum([\"unverified\", \"supported\", \"confirmed\"])\n .describe(\n \"How sure the reporter is: unverified = suspected from reading; supported = evidence points to it; confirmed = demonstrated.\",\n );\n\nexport const findingVerificationMethodSchema = z.enum([\n \"code_inspection\",\n \"static_analysis\",\n \"manual_reproduction\",\n \"unit_test\",\n \"integration_test\",\n \"e2e_test\",\n \"runtime_observation\",\n \"documentation\",\n]);\n\n/**\n * What was done to check the finding. Forces a reporter to distinguish \"I\n * think this is a problem\" from \"I demonstrated it\", which is the axis a human\n * approving fixes cares about most.\n */\nexport const findingVerificationSchema = z.strictObject({\n level: findingVerificationLevelSchema,\n method: findingVerificationMethodSchema,\n summary: z.string().min(1).max(2000).describe(\"What was checked and what it showed.\"),\n limitations: z.string().min(1).max(2000).optional().describe(\"What could not be checked.\"),\n});\n\n/** A single problem found in a repository, as a scanner or agent reports it. */\nexport const findingSchema = z.strictObject({\n title: z.string().min(1).max(200),\n body: z.string().min(1).max(8000).describe(\"The problem, its impact, and how to fix it. Markdown.\"),\n path: z.string().min(1).max(500).optional().describe(\"Repository-relative file path.\"),\n line: z.number().int().min(1).optional(),\n endLine: z.number().int().min(1).optional(),\n priority: findingPrioritySchema,\n category: findingCategorySchema,\n verification: findingVerificationSchema,\n tool: z.string().min(1).max(100).optional().describe(\"Scanner that produced it, e.g. deepsec.\"),\n ruleId: z.string().min(1).max(200).optional().describe(\"Scanner rule or check id, when there is one.\"),\n});\n\nexport type FindingPriority = z.infer<typeof findingPrioritySchema>;\nexport type FindingCategory = z.infer<typeof findingCategorySchema>;\nexport type FindingVerification = z.infer<typeof findingVerificationSchema>;\nexport type Finding = z.infer<typeof findingSchema>;\n\n/**\n * Stable identity of a finding across scans, used as the signal's delivery id\n * so re-reporting is a no-op instead of a second task. A scanner finding is\n * the same problem when the same tool reports the same rule on the same file;\n * its title is model-written prose and changes between runs, so it is left\n * out. Without a rule id the title is all there is, normalised.\n */\nexport function findingFingerprint(repositoryId: string, finding: Finding): string {\n const parts =\n finding.tool !== undefined && finding.ruleId !== undefined && finding.path !== undefined\n ? [repositoryId, finding.tool, finding.ruleId, finding.path]\n : [\n repositoryId,\n finding.tool ?? \"\",\n finding.ruleId ?? \"\",\n finding.path ?? \"\",\n finding.title.trim().toLowerCase().replaceAll(/\\s+/gu, \" \"),\n ];\n return createHash(\"sha256\").update(parts.join(\" \")).digest(\"hex\").slice(0, 32);\n}\n","import { z } from \"zod\";\nimport { vocabularySchema } from \"./schema/common\";\nimport { findingPrioritySchema, type FindingPriority } from \"./schema/finding\";\n\n/**\n * One approval rule. Every listed field must match for the rule to apply;\n * absent fields match anything. Rules are evaluated first-match.\n */\nexport const approvalRuleSchema = z.strictObject({\n source: vocabularySchema.optional().describe(\"Signal source, e.g. security_scan or github_issue.\"),\n kind: vocabularySchema.optional().describe(\"Task kind, e.g. code_change.\"),\n priority: z\n .array(findingPrioritySchema)\n .min(1)\n .optional()\n .describe(\"Finding priorities the rule applies to.\"),\n require: z.boolean().describe(\"Whether matching tasks wait for a human before dispatch.\"),\n});\n\nexport const approvalPolicySchema = z\n .array(approvalRuleSchema)\n .describe(\"First-match rules deciding which tasks need a human before they run.\");\n\nexport type ApprovalRule = z.infer<typeof approvalRuleSchema>;\nexport type ApprovalPolicy = z.infer<typeof approvalPolicySchema>;\n\n/**\n * The default: fixes for security findings wait for a human; everything else\n * runs as it always has. Handoffs between agents (verification) never wait,\n * because a human already approved the work they continue.\n */\nexport const defaultApprovalPolicy: ApprovalPolicy = [\n { kind: \"verification\", require: false },\n { source: \"security_scan\", require: true },\n { require: false },\n];\n\nexport interface ApprovalSubject {\n source?: string;\n kind: string;\n priority?: FindingPriority;\n}\n\n/**\n * Decide at task-creation time whether a task needs approval. Pure: the answer\n * is stamped on the task and never re-evaluated, so a later policy change\n * cannot silently release work a human was expecting to see.\n */\nexport function requiresApproval(policy: ApprovalPolicy, subject: ApprovalSubject): boolean {\n for (const rule of policy) {\n if (rule.source !== undefined && rule.source !== subject.source) continue;\n if (rule.kind !== undefined && rule.kind !== subject.kind) continue;\n if (rule.priority !== undefined) {\n if (subject.priority === undefined || !rule.priority.includes(subject.priority)) continue;\n }\n return rule.require;\n }\n return false;\n}\n","import type { TaskId } from \"./schema/id\";\nimport type { Task } from \"./schema/task\";\nimport { RecordNotFoundError } from \"./store/driver\";\nimport type { FactoryStores } from \"./store/engine\";\n\nexport class DispatchRefusedError extends Error {\n readonly taskId: TaskId;\n readonly reason: string;\n\n constructor(taskId: TaskId, reason: string) {\n super(`dispatch of \"${taskId}\" refused: ${reason}`);\n this.name = \"DispatchRefusedError\";\n this.taskId = taskId;\n this.reason = reason;\n }\n}\n\nexport interface DispatchOptions {\n /**\n * Starts the durable execution for the task (an Eve agent run). Runs after\n * the task has won the queued -> running transition. The execution owns its\n * own provisioning: it creates its Devbox as its first step and patches the\n * task record with the result.\n */\n launch: (task: Task) => Promise<void>;\n}\n\n/**\n * The handshake between recorded work and execution: win the store-gated\n * transition (at most one dispatcher can succeed), then start the run. A\n * launch failure moves the task to failed; a crash between the transition and\n * the launch leaves a running task with no execution, which the sweep reaps.\n */\nexport async function dispatchTask(\n stores: FactoryStores,\n taskId: TaskId,\n options: DispatchOptions,\n): Promise<Task> {\n const task = await stores.tasks.get(taskId);\n if (task === null) {\n throw new RecordNotFoundError(\"tasks\", taskId);\n }\n if (task.kind === \"question\") {\n throw new DispatchRefusedError(taskId, \"question tasks are answered, not dispatched\");\n }\n if (task.approval === \"required\") {\n throw new DispatchRefusedError(taskId, \"awaiting human approval\");\n }\n if (task.approval === \"denied\") {\n throw new DispatchRefusedError(taskId, \"approval was denied\");\n }\n for (const dependencyId of task.dependsOn ?? []) {\n const dependency = await stores.tasks.get(dependencyId);\n if (dependency === null) {\n throw new DispatchRefusedError(taskId, `dependency \"${dependencyId}\" does not exist`);\n }\n if (dependency.changeId === undefined) {\n throw new DispatchRefusedError(\n taskId,\n `dependency \"${dependencyId}\" has not produced a change`,\n );\n }\n }\n\n const running = await stores.tasks.transition(taskId, \"running\");\n try {\n await options.launch(running);\n } catch (error) {\n const reason = (error instanceof Error ? error.message : String(error)).slice(0, 500);\n await stores.tasks\n .transition(taskId, \"failed\", { reason: `launch failed: ${reason}` })\n .catch(() => undefined);\n throw error;\n }\n return running;\n}\n","import { z } from \"zod\";\nimport { isoDateTimeSchema, schemaVersionSchema } from \"./common\";\nimport { changeIdSchema, repositoryIdSchema, taskIdSchema } from \"./id\";\n\nexport const levelSchema = z.enum([\"low\", \"medium\", \"high\"]);\n\nexport const changeStateSchema = z.enum([\n \"verifying\",\n \"ready\",\n \"merged\",\n \"deployed\",\n \"rolled_out\",\n \"rolled_back\",\n \"closed\",\n]);\n\nconst postMergeStates: readonly string[] = [\"merged\", \"deployed\", \"rolled_out\", \"rolled_back\"];\n\nexport const changeEvidenceSchema = z.strictObject({\n reproVerified: z.boolean(),\n testsAdded: z.number().int().min(0),\n checksGreen: z.boolean(),\n attackPassed: z.boolean(),\n scopeMatches: z.boolean(),\n previewUrl: z.url().optional(),\n});\n\nexport const changeSchema = z\n .strictObject({\n schemaVersion: schemaVersionSchema,\n id: changeIdSchema,\n repositoryId: repositoryIdSchema,\n taskId: taskIdSchema.optional(),\n groupId: taskIdSchema.optional(),\n prNumber: z.number().int().min(1),\n prUrl: z.url(),\n author: z.string().min(1),\n risk: levelSchema,\n confidence: levelSchema,\n evidence: changeEvidenceSchema,\n state: changeStateSchema,\n decidedBy: z.string().min(1).optional(),\n createdAt: isoDateTimeSchema,\n updatedAt: isoDateTimeSchema,\n })\n .superRefine((change, ctx) => {\n if (postMergeStates.includes(change.state) && change.decidedBy === undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"decidedBy\"],\n message: `${change.state} changes require decidedBy`,\n });\n }\n });\n\nexport type Level = z.infer<typeof levelSchema>;\nexport type ChangeState = z.infer<typeof changeStateSchema>;\nexport type ChangeEvidence = z.infer<typeof changeEvidenceSchema>;\nexport type Change = z.infer<typeof changeSchema>;\n","import { z } from \"zod\";\nimport {\n isoDateTimeSchema,\n replyToSchema,\n schemaVersionSchema,\n usdSchema,\n vocabularySchema,\n} from \"./common\";\nimport { changeIdSchema, repositoryIdsSchema, signalIdSchema, taskIdSchema } from \"./id\";\n\n/**\n * Kinds the standard loop understands. Any vocabulary value is valid; the\n * kind-scoped rules below apply only to these standard kinds.\n */\nexport const standardTaskKinds = [\n \"code_change\",\n \"verification\",\n \"investigation\",\n \"question\",\n] as const;\n\nexport const taskKindSchema = vocabularySchema.describe(\n \"What kind of work this is, e.g. code_change, question, or a registered custom kind.\",\n);\n\nexport const taskStateSchema = z\n .enum([\"queued\", \"running\", \"verifying\", \"succeeded\", \"failed\", \"needs_human\", \"cancelled\"])\n .describe(\"Lifecycle state. Transitions are fixed; see taskTransitions.\");\n\nexport const taskApprovalSchema = z\n .enum([\"required\", \"granted\", \"denied\"])\n .describe(\n \"Human approval status. Absent means no approval is needed. Stamped required at creation by policy; granted or denied by an operator.\",\n );\n\nexport const harnessSchema = z\n .string()\n .min(1)\n .describe(\"Coding harness used in the devbox, e.g. claude-code or codex.\");\n\nexport const taskOriginSchema = z\n .strictObject({\n signalId: signalIdSchema.optional().describe(\"Signal that led to this task.\"),\n parentTaskId: taskIdSchema.optional().describe(\"Parent task that planned this child.\"),\n operator: z.string().min(1).optional().describe(\"Human operator who requested it.\"),\n })\n .refine(\n (origin) =>\n origin.signalId !== undefined ||\n origin.parentTaskId !== undefined ||\n origin.operator !== undefined,\n { message: \"origin requires a signalId, parentTaskId, or operator\" },\n );\n\nexport const taskDevboxSchema = z.strictObject({\n devboxId: z.string().min(1).describe(\"Devbox running or having run this task.\"),\n remoteId: z.string().min(1).describe(\"Provider-side id of the execution.\"),\n harness: harnessSchema,\n});\n\nexport const taskQuestionSchema = z.strictObject({\n text: z.string().min(1).describe(\"The question a human must answer.\"),\n options: z.array(z.string().min(1)).describe(\"Suggested answers; free-text is also allowed.\"),\n answer: z.string().min(1).optional(),\n answeredBy: z.string().min(1).optional().describe(\"Authenticated operator who answered.\"),\n});\n\nexport const taskSchema = z\n .strictObject({\n schemaVersion: schemaVersionSchema,\n id: taskIdSchema,\n repositoryIds: repositoryIdsSchema\n .optional()\n .describe(\"Repositories the task works on; absent only on a multi-repo parent.\"),\n kind: taskKindSchema,\n area: z\n .string()\n .min(1)\n .optional()\n .describe(\"Investigation area, e.g. onboarding or security. Investigation tasks only.\"),\n state: taskStateSchema,\n approval: taskApprovalSchema.optional(),\n origin: taskOriginSchema,\n dependsOn: z\n .array(taskIdSchema)\n .min(1)\n .optional()\n .describe(\"Sibling tasks that must produce a change before this one may run.\"),\n replyTo: replyToSchema,\n devbox: taskDevboxSchema.optional(),\n attempt: z\n .number()\n .int()\n .min(1)\n .describe(\"Execution attempt, starting at 1; bumps on retry.\"),\n reservedUsd: usdSchema.optional().describe(\"Budget reserved before dispatch.\"),\n settledUsd: usdSchema.optional().describe(\"Measured cost settled after execution.\"),\n question: taskQuestionSchema.optional(),\n changeId: changeIdSchema.optional().describe(\"Change this code_change task produced.\"),\n reportRef: z\n .string()\n .min(1)\n .optional()\n .describe(\"Reference to the report artifact an investigation produced.\"),\n createdAt: isoDateTimeSchema,\n updatedAt: isoDateTimeSchema,\n })\n .superRefine((task, ctx) => {\n if (task.area !== undefined && task.kind !== \"investigation\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"area\"],\n message: \"area is only valid on investigation tasks\",\n });\n }\n if (task.kind === \"question\") {\n if (task.question === undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"question\"],\n message: \"question tasks require a question\",\n });\n }\n if (task.devbox !== undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"devbox\"],\n message: \"question tasks never run in a devbox\",\n });\n }\n } else if (task.question !== undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"question\"],\n message: \"question is only valid on question tasks\",\n });\n }\n if (task.changeId !== undefined && task.kind !== \"code_change\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"changeId\"],\n message: \"changeId is only valid on code_change tasks\",\n });\n }\n if (task.reportRef !== undefined && task.kind !== \"investigation\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"reportRef\"],\n message: \"reportRef is only valid on investigation tasks\",\n });\n }\n });\n\nexport type TaskApproval = z.infer<typeof taskApprovalSchema>;\nexport type TaskKind = z.infer<typeof taskKindSchema>;\nexport type TaskState = z.infer<typeof taskStateSchema>;\nexport type Task = z.infer<typeof taskSchema>;\n"],"mappings":"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","names":["z","z","z","z","z","z"]}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
declare const SCHEMA_VERSION = 1;
|
|
4
|
-
declare const schemaVersionSchema: z.ZodLiteral<1>;
|
|
5
|
-
declare const isoDateTimeSchema: z.ZodISODateTime;
|
|
6
|
-
declare const usdSchema: z.ZodNumber;
|
|
7
|
-
/**
|
|
8
|
-
* Open vocabulary value. Standard values ship as exported constants; custom
|
|
9
|
-
* values matching the pattern are equally valid.
|
|
10
|
-
*/
|
|
11
|
-
declare const vocabularySchema: z.ZodString;
|
|
12
|
-
declare const replyToSchema: z.ZodObject<{
|
|
13
|
-
channel: z.ZodString;
|
|
14
|
-
address: z.ZodString;
|
|
15
|
-
}, z.core.$strict>;
|
|
16
|
-
type ReplyTo = z.infer<typeof replyToSchema>;
|
|
17
|
-
|
|
18
|
-
export { type ReplyTo as R, SCHEMA_VERSION as S, isoDateTimeSchema as i, replyToSchema as r, schemaVersionSchema as s, usdSchema as u, vocabularySchema as v };
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
declare const communicationOutcomes: readonly ["accepted", "started", "succeeded", "failed", "needs_human", "question", "digest", "rolled_back", "budget_warning", "budget_exhausted", "message"];
|
|
4
|
-
declare const communicationOutcomeSchema: z.ZodEnum<{
|
|
5
|
-
accepted: "accepted";
|
|
6
|
-
started: "started";
|
|
7
|
-
succeeded: "succeeded";
|
|
8
|
-
failed: "failed";
|
|
9
|
-
needs_human: "needs_human";
|
|
10
|
-
question: "question";
|
|
11
|
-
digest: "digest";
|
|
12
|
-
rolled_back: "rolled_back";
|
|
13
|
-
budget_warning: "budget_warning";
|
|
14
|
-
budget_exhausted: "budget_exhausted";
|
|
15
|
-
message: "message";
|
|
16
|
-
}>;
|
|
17
|
-
declare const communicationEventSchema: z.ZodObject<{
|
|
18
|
-
eventId: z.ZodString;
|
|
19
|
-
repositoryId: z.ZodString;
|
|
20
|
-
taskId: z.ZodOptional<z.ZodString>;
|
|
21
|
-
changeId: z.ZodOptional<z.ZodString>;
|
|
22
|
-
replyTo: z.ZodObject<{
|
|
23
|
-
channel: z.ZodString;
|
|
24
|
-
address: z.ZodString;
|
|
25
|
-
}, z.core.$strict>;
|
|
26
|
-
outcome: z.ZodEnum<{
|
|
27
|
-
accepted: "accepted";
|
|
28
|
-
started: "started";
|
|
29
|
-
succeeded: "succeeded";
|
|
30
|
-
failed: "failed";
|
|
31
|
-
needs_human: "needs_human";
|
|
32
|
-
question: "question";
|
|
33
|
-
digest: "digest";
|
|
34
|
-
rolled_back: "rolled_back";
|
|
35
|
-
budget_warning: "budget_warning";
|
|
36
|
-
budget_exhausted: "budget_exhausted";
|
|
37
|
-
message: "message";
|
|
38
|
-
}>;
|
|
39
|
-
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
40
|
-
}, z.core.$strict>;
|
|
41
|
-
type CommunicationOutcome = z.infer<typeof communicationOutcomeSchema>;
|
|
42
|
-
type CommunicationEvent = z.infer<typeof communicationEventSchema>;
|
|
43
|
-
interface CommunicationAdapter {
|
|
44
|
-
readonly channel: string;
|
|
45
|
-
deliver(event: CommunicationEvent): Promise<void>;
|
|
46
|
-
}
|
|
47
|
-
interface CommunicationRouter {
|
|
48
|
-
readonly channels: readonly string[];
|
|
49
|
-
deliver(event: CommunicationEvent): Promise<void>;
|
|
50
|
-
}
|
|
51
|
-
declare function createCommunicationRouter(adapters: readonly CommunicationAdapter[]): CommunicationRouter;
|
|
52
|
-
|
|
53
|
-
export { type CommunicationAdapter, type CommunicationEvent, type CommunicationOutcome, type CommunicationRouter, communicationEventSchema, communicationOutcomeSchema, communicationOutcomes, createCommunicationRouter };
|
package/dist/connectors/index.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
changeIdSchema,
|
|
3
|
-
replyToSchema,
|
|
4
|
-
repositoryIdSchema,
|
|
5
|
-
taskIdSchema
|
|
6
|
-
} from "../chunk-2JFES6BA.js";
|
|
7
|
-
|
|
8
|
-
// src/connectors/index.ts
|
|
9
|
-
import { z } from "zod";
|
|
10
|
-
var communicationOutcomes = [
|
|
11
|
-
"accepted",
|
|
12
|
-
"started",
|
|
13
|
-
"succeeded",
|
|
14
|
-
"failed",
|
|
15
|
-
"needs_human",
|
|
16
|
-
"question",
|
|
17
|
-
"digest",
|
|
18
|
-
"rolled_back",
|
|
19
|
-
"budget_warning",
|
|
20
|
-
"budget_exhausted",
|
|
21
|
-
"message"
|
|
22
|
-
];
|
|
23
|
-
var communicationOutcomeSchema = z.enum(communicationOutcomes).describe("Lifecycle outcome a connector should render and deliver.");
|
|
24
|
-
var communicationEventSchema = z.strictObject({
|
|
25
|
-
eventId: z.string().min(1).describe("Stable idempotency key for this delivery."),
|
|
26
|
-
repositoryId: repositoryIdSchema,
|
|
27
|
-
taskId: taskIdSchema.optional(),
|
|
28
|
-
changeId: changeIdSchema.optional(),
|
|
29
|
-
replyTo: replyToSchema,
|
|
30
|
-
outcome: communicationOutcomeSchema,
|
|
31
|
-
data: z.record(z.string(), z.unknown()).describe("Outcome-specific data rendered by the selected connector.")
|
|
32
|
-
});
|
|
33
|
-
function createCommunicationRouter(adapters) {
|
|
34
|
-
const byChannel = /* @__PURE__ */ new Map();
|
|
35
|
-
for (const adapter of adapters) {
|
|
36
|
-
const channel = adapter.channel.trim();
|
|
37
|
-
if (channel.length === 0) {
|
|
38
|
-
throw new Error("Communication adapter channel is required.");
|
|
39
|
-
}
|
|
40
|
-
if (byChannel.has(channel)) {
|
|
41
|
-
throw new Error(`Communication adapter ${channel} is registered more than once.`);
|
|
42
|
-
}
|
|
43
|
-
byChannel.set(channel, adapter);
|
|
44
|
-
}
|
|
45
|
-
const channels = Object.freeze([...byChannel.keys()]);
|
|
46
|
-
return Object.freeze({
|
|
47
|
-
channels,
|
|
48
|
-
async deliver(input) {
|
|
49
|
-
const event = communicationEventSchema.parse(input);
|
|
50
|
-
const adapter = byChannel.get(event.replyTo.channel);
|
|
51
|
-
if (adapter === void 0) {
|
|
52
|
-
throw new Error(`No communication adapter is registered for ${event.replyTo.channel}.`);
|
|
53
|
-
}
|
|
54
|
-
await adapter.deliver(event);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
export {
|
|
59
|
-
communicationEventSchema,
|
|
60
|
-
communicationOutcomeSchema,
|
|
61
|
-
communicationOutcomes,
|
|
62
|
-
createCommunicationRouter
|
|
63
|
-
};
|
|
64
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/connectors/index.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { changeIdSchema, repositoryIdSchema, taskIdSchema } from \"../schema/id\";\nimport { replyToSchema } from \"../schema/common\";\n\nexport const communicationOutcomes = [\n \"accepted\",\n \"started\",\n \"succeeded\",\n \"failed\",\n \"needs_human\",\n \"question\",\n \"digest\",\n \"rolled_back\",\n \"budget_warning\",\n \"budget_exhausted\",\n \"message\",\n] as const;\n\nexport const communicationOutcomeSchema = z\n .enum(communicationOutcomes)\n .describe(\"Lifecycle outcome a connector should render and deliver.\");\n\nexport const communicationEventSchema = z.strictObject({\n eventId: z.string().min(1).describe(\"Stable idempotency key for this delivery.\"),\n repositoryId: repositoryIdSchema,\n taskId: taskIdSchema.optional(),\n changeId: changeIdSchema.optional(),\n replyTo: replyToSchema,\n outcome: communicationOutcomeSchema,\n data: z\n .record(z.string(), z.unknown())\n .describe(\"Outcome-specific data rendered by the selected connector.\"),\n});\n\nexport type CommunicationOutcome = z.infer<typeof communicationOutcomeSchema>;\nexport type CommunicationEvent = z.infer<typeof communicationEventSchema>;\n\nexport interface CommunicationAdapter {\n readonly channel: string;\n deliver(event: CommunicationEvent): Promise<void>;\n}\n\nexport interface CommunicationRouter {\n readonly channels: readonly string[];\n deliver(event: CommunicationEvent): Promise<void>;\n}\n\nexport function createCommunicationRouter(\n adapters: readonly CommunicationAdapter[],\n): CommunicationRouter {\n const byChannel = new Map<string, CommunicationAdapter>();\n for (const adapter of adapters) {\n const channel = adapter.channel.trim();\n if (channel.length === 0) {\n throw new Error(\"Communication adapter channel is required.\");\n }\n if (byChannel.has(channel)) {\n throw new Error(`Communication adapter ${channel} is registered more than once.`);\n }\n byChannel.set(channel, adapter);\n }\n const channels = Object.freeze([...byChannel.keys()]);\n\n return Object.freeze({\n channels,\n async deliver(input: CommunicationEvent): Promise<void> {\n const event = communicationEventSchema.parse(input);\n const adapter = byChannel.get(event.replyTo.channel);\n if (adapter === undefined) {\n throw new Error(`No communication adapter is registered for ${event.replyTo.channel}.`);\n }\n await adapter.deliver(event);\n },\n });\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,SAAS;AAIX,IAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,6BAA6B,EACvC,KAAK,qBAAqB,EAC1B,SAAS,0DAA0D;AAE/D,IAAM,2BAA2B,EAAE,aAAa;AAAA,EACrD,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,2CAA2C;AAAA,EAC/E,cAAc;AAAA,EACd,QAAQ,aAAa,SAAS;AAAA,EAC9B,UAAU,eAAe,SAAS;AAAA,EAClC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM,EACH,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAC9B,SAAS,2DAA2D;AACzE,CAAC;AAeM,SAAS,0BACd,UACqB;AACrB,QAAM,YAAY,oBAAI,IAAkC;AACxD,aAAW,WAAW,UAAU;AAC9B,UAAM,UAAU,QAAQ,QAAQ,KAAK;AACrC,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AACA,QAAI,UAAU,IAAI,OAAO,GAAG;AAC1B,YAAM,IAAI,MAAM,yBAAyB,OAAO,gCAAgC;AAAA,IAClF;AACA,cAAU,IAAI,SAAS,OAAO;AAAA,EAChC;AACA,QAAM,WAAW,OAAO,OAAO,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC;AAEpD,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,MAAM,QAAQ,OAA0C;AACtD,YAAM,QAAQ,yBAAyB,MAAM,KAAK;AAClD,YAAM,UAAU,UAAU,IAAI,MAAM,QAAQ,OAAO;AACnD,UAAI,YAAY,QAAW;AACzB,cAAM,IAAI,MAAM,8CAA8C,MAAM,QAAQ,OAAO,GAAG;AAAA,MACxF;AACA,YAAM,QAAQ,QAAQ,KAAK;AAAA,IAC7B;AAAA,EACF,CAAC;AACH;","names":[]}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
type CollectionName = "repositories" | "signals" | "tasks" | "changes" | "receipts";
|
|
2
|
-
interface StoredRecord {
|
|
3
|
-
readonly value: unknown;
|
|
4
|
-
readonly version: number;
|
|
5
|
-
}
|
|
6
|
-
interface StoredEntry {
|
|
7
|
-
readonly id: string;
|
|
8
|
-
readonly record: StoredRecord;
|
|
9
|
-
}
|
|
10
|
-
declare class RecordExistsError extends Error {
|
|
11
|
-
constructor(collection: CollectionName, id: string);
|
|
12
|
-
}
|
|
13
|
-
declare class RecordNotFoundError extends Error {
|
|
14
|
-
constructor(collection: CollectionName, id: string);
|
|
15
|
-
}
|
|
16
|
-
declare class VersionConflictError extends Error {
|
|
17
|
-
constructor(collection: CollectionName, id: string, expectedVersion: number);
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Raw persistence contract. Drivers store opaque values and enforce nothing
|
|
21
|
-
* about their content; every invariant lives in the engine above. `update`
|
|
22
|
-
* must be an atomic compare-and-swap on `expectedVersion`.
|
|
23
|
-
*/
|
|
24
|
-
interface StoreDriver {
|
|
25
|
-
readonly name: string;
|
|
26
|
-
get(collection: CollectionName, id: string): Promise<StoredRecord | null>;
|
|
27
|
-
insert(collection: CollectionName, id: string, value: unknown): Promise<void>;
|
|
28
|
-
update(collection: CollectionName, id: string, value: unknown, expectedVersion: number): Promise<void>;
|
|
29
|
-
list(collection: CollectionName): Promise<readonly StoredEntry[]>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export { type CollectionName as C, RecordExistsError as R, type StoreDriver as S, VersionConflictError as V, RecordNotFoundError as a, type StoredEntry as b, type StoredRecord as c };
|