@abelxiaoxing/cadence 1.0.14 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +39 -13
  2. package/agents/contract-reviewer.md +2 -2
  3. package/agents/design-explorer.md +1 -1
  4. package/agents/diagnosis-worker.md +6 -3
  5. package/agents/implementation-worker.md +14 -9
  6. package/config/.env.example +5 -17
  7. package/config/routes.example.json +42 -0
  8. package/package.json +3 -3
  9. package/prompts/abel-design.md +206 -228
  10. package/prompts/abel-diagnose.md +39 -18
  11. package/prompts/abel-implement.md +122 -178
  12. package/prompts/abel-init.md +36 -33
  13. package/skills/abel-workflow/SKILL.md +190 -168
  14. package/src/apply-transaction.ts +1427 -0
  15. package/src/artifact-store.ts +204 -0
  16. package/src/child-session.ts +136 -17
  17. package/src/contracts.ts +121 -696
  18. package/src/control-contracts.ts +246 -0
  19. package/src/delivery-compiler.ts +1118 -0
  20. package/src/design-control.ts +846 -0
  21. package/src/design-journal.ts +1569 -0
  22. package/src/file-snapshot.ts +5 -0
  23. package/src/implement-graph.ts +11 -4
  24. package/src/index.ts +1833 -118
  25. package/src/isolation-backend.ts +269 -0
  26. package/src/packet-runtime.ts +533 -0
  27. package/src/parent-provider.ts +23 -4
  28. package/src/route-policy.ts +483 -0
  29. package/src/run-state.ts +430 -0
  30. package/src/run-store.ts +990 -0
  31. package/src/safe-path.ts +11 -0
  32. package/src/scoped-tools.ts +36 -0
  33. package/src/state-root.ts +215 -0
  34. package/src/subagent-activity.ts +526 -27
  35. package/src/submit-tool.ts +274 -0
  36. package/src/task-ledger.ts +1380 -0
  37. package/src/verification-capability.ts +560 -45
  38. package/src/worker-broker.ts +703 -0
  39. package/src/workflow-engine.ts +7706 -0
  40. package/src/workspace-store.ts +544 -0
  41. package/src/candidate-preflight.ts +0 -1618
  42. package/src/drain.ts +0 -20
  43. package/src/patch.ts +0 -505
  44. package/src/result-store.ts +0 -312
  45. package/src/runtime.ts +0 -2436
  46. package/src/scheduler.ts +0 -384
  47. package/src/subagent-endpoint.ts +0 -158
  48. package/src/worker.ts +0 -204
@@ -1,312 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { isDeepStrictEqual } from "node:util";
3
- import type {
4
- BaselineEntry,
5
- VerificationContract,
6
- } from "./candidate-preflight.ts";
7
- import {
8
- cloneVerificationContract,
9
- type ImplementationPhase,
10
- } from "./contracts.ts";
11
- import type { Bound, DirBound, FileBound } from "./file-snapshot.ts";
12
- import { snapshotFiles } from "./file-snapshot.ts";
13
-
14
- export interface RetainedCandidateIdentity {
15
- stage: "abel-implement";
16
- canonicalRoot: string;
17
- root: string;
18
- changeId: string;
19
- taskId: string;
20
- originRequestId: string;
21
- phase: ImplementationPhase;
22
- launchIndex: 0 | 1;
23
- }
24
-
25
- export interface RetainedCandidateFacts extends RetainedCandidateIdentity {
26
- writeSet: string[];
27
- approvedDependencies: string[];
28
- snapshot: Bound;
29
- }
30
-
31
- export interface RetainedResult {
32
- id: string;
33
- diff: Buffer;
34
- stage?: RetainedCandidateIdentity["stage"];
35
- canonicalRoot?: string;
36
- changeId?: string;
37
- taskId?: string;
38
- originRequestId?: string;
39
- phase?: ImplementationPhase;
40
- launchIndex?: 0 | 1;
41
- writeSet: string[];
42
- approvedDependencies: string[];
43
- root: string;
44
- snapshot: Bound;
45
- baseline: BaselineEntry[];
46
- verification?: VerificationContract;
47
- packageManifest?: FileBound;
48
- lockfile?: FileBound;
49
- dependencyTarget?: FileBound | DirBound;
50
- }
51
-
52
- export type BoundRetainedResult = RetainedResult & RetainedCandidateIdentity;
53
-
54
- interface RetainCandidateData {
55
- diff: string;
56
- writeSet: string[];
57
- approvedDependencies?: string[];
58
- root: string;
59
- snapshot?: Bound;
60
- baseline?: BaselineEntry[];
61
- verification?: VerificationContract;
62
- packageManifest?: FileBound;
63
- lockfile?: FileBound;
64
- dependencyTarget?: FileBound | DirBound;
65
- }
66
-
67
- type RetainInput = RetainCandidateData & Partial<RetainedCandidateIdentity>;
68
-
69
- const IDENTITY_KEYS = [
70
- "stage",
71
- "canonicalRoot",
72
- "changeId",
73
- "taskId",
74
- "originRequestId",
75
- "phase",
76
- "launchIndex",
77
- ] as const;
78
-
79
- function hasCompleteIdentity(
80
- value: RetainedResult | RetainInput,
81
- ): value is (RetainedResult | RetainInput) & RetainedCandidateIdentity {
82
- return IDENTITY_KEYS.every((key) => value[key] !== undefined);
83
- }
84
-
85
- function hasAnyIdentity(value: RetainedResult | RetainInput): boolean {
86
- return IDENTITY_KEYS.some((key) => value[key] !== undefined);
87
- }
88
-
89
- function cloneIdentity(identity: RetainedCandidateIdentity) {
90
- return {
91
- stage: identity.stage,
92
- canonicalRoot: identity.canonicalRoot,
93
- changeId: identity.changeId,
94
- taskId: identity.taskId,
95
- originRequestId: identity.originRequestId,
96
- phase: identity.phase,
97
- launchIndex: identity.launchIndex,
98
- };
99
- }
100
-
101
- function cloneRetained(retained: RetainedResult): RetainedResult {
102
- const clone: RetainedResult = {
103
- ...retained,
104
- diff: Buffer.from(retained.diff),
105
- writeSet: [...retained.writeSet],
106
- approvedDependencies: [...retained.approvedDependencies],
107
- snapshot: structuredClone(retained.snapshot),
108
- baseline: retained.baseline.map((entry) => ({ ...entry })),
109
- };
110
- if (retained.verification) {
111
- clone.verification = cloneVerificationContract(retained.verification);
112
- }
113
- if (retained.packageManifest) {
114
- clone.packageManifest = { ...retained.packageManifest };
115
- }
116
- if (retained.lockfile) clone.lockfile = { ...retained.lockfile };
117
- if (retained.dependencyTarget) {
118
- clone.dependencyTarget = { ...retained.dependencyTarget };
119
- }
120
- return clone;
121
- }
122
-
123
- export class ResultStore {
124
- private readonly results = new Map<string, RetainedResult>();
125
- private readonly sealedResults = new Map<string, RetainedResult>();
126
- private readonly sealedCandidateFacts = new Map<
127
- string,
128
- RetainedCandidateFacts
129
- >();
130
-
131
- retain(input: RetainInput): string {
132
- if (hasAnyIdentity(input) && !hasCompleteIdentity(input)) {
133
- throw new Error("retained candidate identity is incomplete");
134
- }
135
- const id = randomUUID();
136
- const retained: RetainedResult = {
137
- id,
138
- diff: Buffer.from(input.diff, "utf8"),
139
- ...(hasCompleteIdentity(input) ? cloneIdentity(input) : {}),
140
- writeSet: [...input.writeSet],
141
- approvedDependencies: [...(input.approvedDependencies ?? [])],
142
- root: input.root,
143
- snapshot: structuredClone(
144
- input.snapshot ?? snapshotFiles(input.root, input.writeSet),
145
- ),
146
- baseline: (input.baseline ?? []).map((entry) => ({ ...entry })),
147
- ...(input.verification === undefined
148
- ? {}
149
- : {
150
- verification: cloneVerificationContract(input.verification),
151
- }),
152
- ...(input.packageManifest === undefined
153
- ? {}
154
- : { packageManifest: { ...input.packageManifest } }),
155
- ...(input.lockfile === undefined
156
- ? {}
157
- : { lockfile: { ...input.lockfile } }),
158
- ...(input.dependencyTarget === undefined
159
- ? {}
160
- : { dependencyTarget: { ...input.dependencyTarget } }),
161
- };
162
- this.results.set(id, retained);
163
- this.sealedResults.set(id, cloneRetained(retained));
164
- if (hasCompleteIdentity(retained)) {
165
- this.sealedCandidateFacts.set(id, this.cloneFacts(retained));
166
- }
167
- return id;
168
- }
169
-
170
- get(id: string): RetainedResult | undefined {
171
- const retained = this.results.get(id);
172
- return retained ? cloneRetained(retained) : undefined;
173
- }
174
-
175
- hasCandidateIdentity(id: string): boolean {
176
- const retained = this.results.get(id);
177
- if (!retained) return false;
178
- this.assertIntegrity(id, retained);
179
- return hasAnyIdentity(retained);
180
- }
181
-
182
- bindIdentity(
183
- id: string,
184
- identity: RetainedCandidateIdentity,
185
- ): BoundRetainedResult {
186
- const retained = this.results.get(id);
187
- if (!retained) throw new Error("retained result not found");
188
- this.assertIntegrity(id, retained);
189
- if (hasAnyIdentity(retained)) {
190
- if (
191
- !hasCompleteIdentity(retained) ||
192
- !this.matchesIdentity(retained, identity)
193
- ) {
194
- throw new Error("retained candidate identity mismatch");
195
- }
196
- return cloneRetained(retained) as BoundRetainedResult;
197
- }
198
- if (retained.root !== identity.root) {
199
- throw new Error("retained candidate identity mismatch");
200
- }
201
- Object.assign(retained, cloneIdentity(identity));
202
- this.sealedResults.set(id, cloneRetained(retained));
203
- return cloneRetained(retained) as BoundRetainedResult;
204
- }
205
-
206
- resolveIdentity(
207
- id: string,
208
- expected: RetainedCandidateFacts,
209
- ): BoundRetainedResult {
210
- const retained = this.results.get(id);
211
- if (!retained) throw new Error("retained result not found");
212
- this.assertIntegrity(id, retained);
213
- if (
214
- !hasCompleteIdentity(retained) ||
215
- !this.matchesIdentity(retained, expected) ||
216
- !isDeepStrictEqual(retained.writeSet, expected.writeSet) ||
217
- !isDeepStrictEqual(
218
- retained.approvedDependencies,
219
- expected.approvedDependencies,
220
- )
221
- ) {
222
- throw new Error("retained candidate identity mismatch");
223
- }
224
- const sealed = this.sealedCandidateFacts.get(id);
225
- if (sealed) {
226
- if (
227
- !this.matchesIdentity(retained, sealed) ||
228
- !isDeepStrictEqual(retained.writeSet, sealed.writeSet) ||
229
- !isDeepStrictEqual(
230
- retained.approvedDependencies,
231
- sealed.approvedDependencies,
232
- ) ||
233
- !isDeepStrictEqual(retained.snapshot, sealed.snapshot)
234
- ) {
235
- throw new Error("retained candidate identity mismatch");
236
- }
237
- } else {
238
- if (!isDeepStrictEqual(retained.snapshot, expected.snapshot)) {
239
- throw new Error("retained candidate identity mismatch");
240
- }
241
- this.sealedCandidateFacts.set(id, this.cloneFacts(retained));
242
- }
243
- return cloneRetained(retained) as BoundRetainedResult;
244
- }
245
-
246
- resolveForApply(id: string): RetainedResult {
247
- const retained = this.results.get(id);
248
- if (!retained) throw new Error("retained result not found");
249
- this.assertIntegrity(id, retained);
250
- return cloneRetained(retained);
251
- }
252
-
253
- private assertIntegrity(id: string, retained: RetainedResult): void {
254
- const sealed = this.sealedResults.get(id);
255
- if (sealed && isDeepStrictEqual(retained, sealed)) return;
256
- const identityChanged =
257
- sealed !== undefined &&
258
- (IDENTITY_KEYS.some((key) => retained[key] !== sealed[key]) ||
259
- retained.root !== sealed.root ||
260
- !isDeepStrictEqual(retained.writeSet, sealed.writeSet) ||
261
- !isDeepStrictEqual(
262
- retained.approvedDependencies,
263
- sealed.approvedDependencies,
264
- ) ||
265
- !isDeepStrictEqual(retained.snapshot, sealed.snapshot));
266
- throw new Error(
267
- identityChanged
268
- ? "retained candidate identity mismatch"
269
- : "retained candidate integrity mismatch",
270
- );
271
- }
272
-
273
- private cloneFacts(retained: BoundRetainedResult): RetainedCandidateFacts {
274
- return {
275
- ...cloneIdentity(retained),
276
- root: retained.root,
277
- writeSet: [...retained.writeSet],
278
- approvedDependencies: [...retained.approvedDependencies],
279
- snapshot: structuredClone(retained.snapshot),
280
- };
281
- }
282
-
283
- private matchesIdentity(
284
- retained: BoundRetainedResult,
285
- expected: RetainedCandidateIdentity,
286
- ): boolean {
287
- return (
288
- retained.stage === expected.stage &&
289
- retained.canonicalRoot === expected.canonicalRoot &&
290
- retained.root === expected.root &&
291
- retained.changeId === expected.changeId &&
292
- retained.taskId === expected.taskId &&
293
- retained.originRequestId === expected.originRequestId &&
294
- retained.phase === expected.phase &&
295
- retained.launchIndex === expected.launchIndex
296
- );
297
- }
298
-
299
- discard(id: string): boolean {
300
- this.sealedResults.delete(id);
301
- this.sealedCandidateFacts.delete(id);
302
- return this.results.delete(id);
303
- }
304
- clear(): void {
305
- this.results.clear();
306
- this.sealedResults.clear();
307
- this.sealedCandidateFacts.clear();
308
- }
309
- get size(): number {
310
- return this.results.size;
311
- }
312
- }