@synergenius/flowweaver-pack-weaver 0.5.3 → 0.6.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.
- package/dist/bot/design-checker.d.ts +24 -0
- package/dist/bot/design-checker.d.ts.map +1 -0
- package/dist/bot/design-checker.js +269 -0
- package/dist/bot/design-checker.js.map +1 -0
- package/dist/bot/file-validator.d.ts +5 -2
- package/dist/bot/file-validator.d.ts.map +1 -1
- package/dist/bot/file-validator.js +22 -1
- package/dist/bot/file-validator.js.map +1 -1
- package/dist/bot/genesis-prompt-context.d.ts +31 -0
- package/dist/bot/genesis-prompt-context.d.ts.map +1 -0
- package/dist/bot/genesis-prompt-context.js +121 -0
- package/dist/bot/genesis-prompt-context.js.map +1 -0
- package/dist/bot/genesis-store.d.ts +11 -1
- package/dist/bot/genesis-store.d.ts.map +1 -1
- package/dist/bot/genesis-store.js +65 -0
- package/dist/bot/genesis-store.js.map +1 -1
- package/dist/bot/types.d.ts +41 -1
- package/dist/bot/types.d.ts.map +1 -1
- package/dist/cli-handlers.d.ts +2 -1
- package/dist/cli-handlers.d.ts.map +1 -1
- package/dist/cli-handlers.js +130 -92
- package/dist/cli-handlers.js.map +1 -1
- package/dist/docs/docs/weaver-config.md +8 -14
- package/dist/docs/weaver-config.md +8 -14
- package/dist/node-types/exec-validate-retry.d.ts.map +1 -1
- package/dist/node-types/exec-validate-retry.js +23 -3
- package/dist/node-types/exec-validate-retry.js.map +1 -1
- package/dist/node-types/genesis-apply-retry.d.ts +6 -3
- package/dist/node-types/genesis-apply-retry.d.ts.map +1 -1
- package/dist/node-types/genesis-apply-retry.js +18 -10
- package/dist/node-types/genesis-apply-retry.js.map +1 -1
- package/dist/node-types/genesis-approve.d.ts.map +1 -1
- package/dist/node-types/genesis-approve.js +6 -1
- package/dist/node-types/genesis-approve.js.map +1 -1
- package/dist/node-types/genesis-diff-workflow.d.ts.map +1 -1
- package/dist/node-types/genesis-diff-workflow.js +30 -2
- package/dist/node-types/genesis-diff-workflow.js.map +1 -1
- package/dist/node-types/genesis-escrow-grace.d.ts +15 -0
- package/dist/node-types/genesis-escrow-grace.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-grace.js +52 -0
- package/dist/node-types/genesis-escrow-grace.js.map +1 -0
- package/dist/node-types/genesis-escrow-migrate.d.ts +21 -0
- package/dist/node-types/genesis-escrow-migrate.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-migrate.js +116 -0
- package/dist/node-types/genesis-escrow-migrate.js.map +1 -0
- package/dist/node-types/genesis-escrow-recover.d.ts +15 -0
- package/dist/node-types/genesis-escrow-recover.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-recover.js +90 -0
- package/dist/node-types/genesis-escrow-recover.js.map +1 -0
- package/dist/node-types/genesis-escrow-stage.d.ts +17 -0
- package/dist/node-types/genesis-escrow-stage.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-stage.js +86 -0
- package/dist/node-types/genesis-escrow-stage.js.map +1 -0
- package/dist/node-types/genesis-escrow-validate.d.ts +17 -0
- package/dist/node-types/genesis-escrow-validate.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-validate.js +110 -0
- package/dist/node-types/genesis-escrow-validate.js.map +1 -0
- package/dist/node-types/genesis-load-config.d.ts.map +1 -1
- package/dist/node-types/genesis-load-config.js +1 -0
- package/dist/node-types/genesis-load-config.js.map +1 -1
- package/dist/node-types/genesis-observe.d.ts.map +1 -1
- package/dist/node-types/genesis-observe.js +2 -0
- package/dist/node-types/genesis-observe.js.map +1 -1
- package/dist/node-types/genesis-propose.d.ts.map +1 -1
- package/dist/node-types/genesis-propose.js +41 -33
- package/dist/node-types/genesis-propose.js.map +1 -1
- package/dist/node-types/genesis-report.d.ts +4 -2
- package/dist/node-types/genesis-report.d.ts.map +1 -1
- package/dist/node-types/genesis-report.js +43 -17
- package/dist/node-types/genesis-report.js.map +1 -1
- package/dist/node-types/genesis-try-apply.d.ts.map +1 -1
- package/dist/node-types/genesis-try-apply.js +33 -0
- package/dist/node-types/genesis-try-apply.js.map +1 -1
- package/dist/node-types/genesis-update-history.d.ts.map +1 -1
- package/dist/node-types/genesis-update-history.js +21 -8
- package/dist/node-types/genesis-update-history.js.map +1 -1
- package/dist/node-types/genesis-validate-proposal.d.ts.map +1 -1
- package/dist/node-types/genesis-validate-proposal.js +62 -5
- package/dist/node-types/genesis-validate-proposal.js.map +1 -1
- package/dist/templates/index.d.ts +2 -4
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +1 -3
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/weaver-bot-template.d.ts +9 -1
- package/dist/templates/weaver-bot-template.d.ts.map +1 -1
- package/dist/templates/weaver-bot-template.js.map +1 -1
- package/dist/workflows/genesis-task.d.ts +25 -17
- package/dist/workflows/genesis-task.d.ts.map +1 -1
- package/dist/workflows/genesis-task.js +25 -17
- package/dist/workflows/genesis-task.js.map +1 -1
- package/dist/workflows/index.d.ts +0 -1
- package/dist/workflows/index.d.ts.map +1 -1
- package/dist/workflows/index.js +0 -1
- package/dist/workflows/index.js.map +1 -1
- package/flowweaver.manifest.json +10 -10
- package/package.json +3 -3
- package/dist/templates/weaver-template.d.ts +0 -11
- package/dist/templates/weaver-template.d.ts.map +0 -1
- package/dist/templates/weaver-template.js +0 -53
- package/dist/templates/weaver-template.js.map +0 -1
- package/dist/workflows/weaver.d.ts +0 -24
- package/dist/workflows/weaver.d.ts.map +0 -1
- package/dist/workflows/weaver.js +0 -28
- package/dist/workflows/weaver.js.map +0 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weaver Design Quality Checker
|
|
3
|
+
*
|
|
4
|
+
* Heuristic, context-dependent design checks that the bot evaluates during
|
|
5
|
+
* its exec-validate-retry loop and genesis proposal validation. These are
|
|
6
|
+
* opinionated recommendations, not core validator rules.
|
|
7
|
+
*
|
|
8
|
+
* Checks structural quality, complexity limits, and completeness.
|
|
9
|
+
*/
|
|
10
|
+
import type { TWorkflowAST } from '@synergenius/flow-weaver';
|
|
11
|
+
export interface DesignCheck {
|
|
12
|
+
code: string;
|
|
13
|
+
severity: 'info' | 'warning' | 'error';
|
|
14
|
+
message: string;
|
|
15
|
+
nodeId?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface DesignReport {
|
|
18
|
+
score: number;
|
|
19
|
+
checks: DesignCheck[];
|
|
20
|
+
passed: number;
|
|
21
|
+
failed: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function checkDesignQuality(ast: TWorkflowAST): DesignReport;
|
|
24
|
+
//# sourceMappingURL=design-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-checker.d.ts","sourceRoot":"","sources":["../../src/bot/design-checker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAkC,MAAM,0BAA0B,CAAC;AAE7F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAiRD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY,CA6BlE"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weaver Design Quality Checker
|
|
3
|
+
*
|
|
4
|
+
* Heuristic, context-dependent design checks that the bot evaluates during
|
|
5
|
+
* its exec-validate-retry loop and genesis proposal validation. These are
|
|
6
|
+
* opinionated recommendations, not core validator rules.
|
|
7
|
+
*
|
|
8
|
+
* Checks structural quality, complexity limits, and completeness.
|
|
9
|
+
*/
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Helpers
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
function resolveNodeType(ast, instance) {
|
|
14
|
+
return ast.nodeTypes.find((nt) => nt.name === instance.nodeType || nt.functionName === instance.nodeType);
|
|
15
|
+
}
|
|
16
|
+
function getOutgoing(ast, nodeId, portName) {
|
|
17
|
+
return ast.connections.filter((c) => {
|
|
18
|
+
if (c.from.node !== nodeId)
|
|
19
|
+
return false;
|
|
20
|
+
if (portName && c.from.port !== portName)
|
|
21
|
+
return false;
|
|
22
|
+
return true;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function getIncoming(ast, nodeId) {
|
|
26
|
+
return ast.connections.filter((c) => c.to.node === nodeId);
|
|
27
|
+
}
|
|
28
|
+
const GENERIC_ID_PATTERN = /^(node|n|tmp|x|test|foo|bar)\d*$/i;
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Structural Quality Checks
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
function checkVisualAnnotations(ast) {
|
|
33
|
+
const checks = [];
|
|
34
|
+
for (const inst of ast.instances) {
|
|
35
|
+
const hasColor = inst.config?.color;
|
|
36
|
+
const hasIcon = inst.config?.icon;
|
|
37
|
+
if (!hasColor && !hasIcon) {
|
|
38
|
+
checks.push({
|
|
39
|
+
code: 'WEAVER_MISSING_VISUALS',
|
|
40
|
+
severity: 'info',
|
|
41
|
+
message: `Node '${inst.id}' has no @color or @icon set. Visual annotations help readability.`,
|
|
42
|
+
nodeId: inst.id,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return checks;
|
|
47
|
+
}
|
|
48
|
+
function checkDescriptiveIds(ast) {
|
|
49
|
+
const checks = [];
|
|
50
|
+
for (const inst of ast.instances) {
|
|
51
|
+
if (GENERIC_ID_PATTERN.test(inst.id)) {
|
|
52
|
+
checks.push({
|
|
53
|
+
code: 'WEAVER_GENERIC_NODE_ID',
|
|
54
|
+
severity: 'warning',
|
|
55
|
+
message: `Node instance ID '${inst.id}' is generic. Use a descriptive ID that reflects the node's purpose.`,
|
|
56
|
+
nodeId: inst.id,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return checks;
|
|
61
|
+
}
|
|
62
|
+
function checkFlowDirection(ast) {
|
|
63
|
+
const checks = [];
|
|
64
|
+
if (!ast.ui?.instances || ast.ui.instances.length < 2)
|
|
65
|
+
return checks;
|
|
66
|
+
// Check if x-positions generally increase along step connections
|
|
67
|
+
const posMap = new Map();
|
|
68
|
+
for (const uiNode of ast.ui.instances) {
|
|
69
|
+
posMap.set(uiNode.name, uiNode.x);
|
|
70
|
+
}
|
|
71
|
+
let violations = 0;
|
|
72
|
+
let total = 0;
|
|
73
|
+
for (const conn of ast.connections) {
|
|
74
|
+
const fromX = posMap.get(conn.from.node);
|
|
75
|
+
const toX = posMap.get(conn.to.node);
|
|
76
|
+
if (fromX !== undefined && toX !== undefined) {
|
|
77
|
+
total++;
|
|
78
|
+
if (toX < fromX - 50)
|
|
79
|
+
violations++; // Allow small tolerance
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (total > 0 && violations / total > 0.3) {
|
|
83
|
+
checks.push({
|
|
84
|
+
code: 'WEAVER_LAYOUT_DIRECTION',
|
|
85
|
+
severity: 'info',
|
|
86
|
+
message: `${violations} of ${total} connections flow right-to-left. Consider a left-to-right or top-to-bottom layout for readability.`,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return checks;
|
|
90
|
+
}
|
|
91
|
+
function checkDescription(ast) {
|
|
92
|
+
if (!ast.description) {
|
|
93
|
+
return [{
|
|
94
|
+
code: 'WEAVER_NO_DESCRIPTION',
|
|
95
|
+
severity: 'info',
|
|
96
|
+
message: 'Workflow has no JSDoc description. A short summary helps collaborators understand its purpose.',
|
|
97
|
+
}];
|
|
98
|
+
}
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
// Complexity Checks
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
function checkNodeCount(ast) {
|
|
105
|
+
const checks = [];
|
|
106
|
+
const count = ast.instances.length;
|
|
107
|
+
if (count > 50) {
|
|
108
|
+
checks.push({
|
|
109
|
+
code: 'WEAVER_TOO_MANY_NODES',
|
|
110
|
+
severity: 'error',
|
|
111
|
+
message: `Workflow has ${count} nodes (limit: 50). Extract sub-workflows to reduce complexity.`,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
else if (count > 30) {
|
|
115
|
+
checks.push({
|
|
116
|
+
code: 'WEAVER_TOO_MANY_NODES',
|
|
117
|
+
severity: 'warning',
|
|
118
|
+
message: `Workflow has ${count} nodes (recommended limit: 30). Consider extracting sub-workflows.`,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return checks;
|
|
122
|
+
}
|
|
123
|
+
function checkScopeNesting(ast) {
|
|
124
|
+
const checks = [];
|
|
125
|
+
if (!ast.scopes)
|
|
126
|
+
return checks;
|
|
127
|
+
// Build parent chain: instance -> scope -> parent instance
|
|
128
|
+
const instanceScopeDepth = new Map();
|
|
129
|
+
function getDepth(instanceId, visited) {
|
|
130
|
+
if (visited.has(instanceId))
|
|
131
|
+
return 0;
|
|
132
|
+
visited.add(instanceId);
|
|
133
|
+
const cached = instanceScopeDepth.get(instanceId);
|
|
134
|
+
if (cached !== undefined)
|
|
135
|
+
return cached;
|
|
136
|
+
const inst = ast.instances.find((i) => i.id === instanceId);
|
|
137
|
+
if (!inst?.parent) {
|
|
138
|
+
instanceScopeDepth.set(instanceId, 0);
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
const parentDepth = getDepth(inst.parent.id, visited);
|
|
142
|
+
const depth = parentDepth + 1;
|
|
143
|
+
instanceScopeDepth.set(instanceId, depth);
|
|
144
|
+
return depth;
|
|
145
|
+
}
|
|
146
|
+
for (const inst of ast.instances) {
|
|
147
|
+
const depth = getDepth(inst.id, new Set());
|
|
148
|
+
if (depth > 3) {
|
|
149
|
+
checks.push({
|
|
150
|
+
code: 'WEAVER_DEEP_NESTING',
|
|
151
|
+
severity: 'warning',
|
|
152
|
+
message: `Node '${inst.id}' is nested ${depth} scopes deep (limit: 3). Deep nesting makes workflows hard to follow.`,
|
|
153
|
+
nodeId: inst.id,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return checks;
|
|
158
|
+
}
|
|
159
|
+
function checkFanInComplexity(ast) {
|
|
160
|
+
const checks = [];
|
|
161
|
+
for (const inst of ast.instances) {
|
|
162
|
+
const dataIn = getIncoming(ast, inst.id).filter((c) => c.to.port !== 'execute' && c.to.port !== 'start');
|
|
163
|
+
if (dataIn.length > 5) {
|
|
164
|
+
checks.push({
|
|
165
|
+
code: 'WEAVER_HIGH_FANIN',
|
|
166
|
+
severity: 'warning',
|
|
167
|
+
message: `Node '${inst.id}' receives ${dataIn.length} data connections (limit: 5). This may be a bottleneck.`,
|
|
168
|
+
nodeId: inst.id,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return checks;
|
|
173
|
+
}
|
|
174
|
+
function checkFanOutComplexity(ast) {
|
|
175
|
+
const checks = [];
|
|
176
|
+
const stepPorts = new Set(['onSuccess', 'onFailure', 'execute', 'start', 'success', 'failure']);
|
|
177
|
+
for (const inst of ast.instances) {
|
|
178
|
+
const stepOut = getOutgoing(ast, inst.id).filter((c) => stepPorts.has(c.from.port));
|
|
179
|
+
const uniqueTargets = new Set(stepOut.map((c) => c.to.node));
|
|
180
|
+
if (uniqueTargets.size > 4) {
|
|
181
|
+
checks.push({
|
|
182
|
+
code: 'WEAVER_HIGH_FANOUT',
|
|
183
|
+
severity: 'warning',
|
|
184
|
+
message: `Node '${inst.id}' fans out to ${uniqueTargets.size} step targets (limit: 4). High branching increases complexity.`,
|
|
185
|
+
nodeId: inst.id,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return checks;
|
|
190
|
+
}
|
|
191
|
+
// ---------------------------------------------------------------------------
|
|
192
|
+
// Completeness Checks
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
function checkNotificationPresence(ast) {
|
|
195
|
+
const checks = [];
|
|
196
|
+
// Check if workflow has side-effect nodes (heuristic: async nodes with write/send/push-like names)
|
|
197
|
+
const sideEffectPattern = /write|send|push|post|create|delete|update|deploy|publish|upload|notify/i;
|
|
198
|
+
const hasSideEffects = ast.instances.some((inst) => {
|
|
199
|
+
const nt = resolveNodeType(ast, inst);
|
|
200
|
+
const nameHint = `${inst.id} ${nt?.name ?? ''} ${nt?.functionName ?? ''} ${nt?.label ?? ''}`;
|
|
201
|
+
return sideEffectPattern.test(nameHint);
|
|
202
|
+
});
|
|
203
|
+
if (!hasSideEffects)
|
|
204
|
+
return checks;
|
|
205
|
+
// Check if there's a notification-like node
|
|
206
|
+
const notifyPattern = /notify|notification|alert|report|summary|slack|email|webhook|message/i;
|
|
207
|
+
const hasNotification = ast.instances.some((inst) => {
|
|
208
|
+
const nt = resolveNodeType(ast, inst);
|
|
209
|
+
const nameHint = `${inst.id} ${nt?.name ?? ''} ${nt?.functionName ?? ''} ${nt?.label ?? ''}`;
|
|
210
|
+
return notifyPattern.test(nameHint);
|
|
211
|
+
});
|
|
212
|
+
if (!hasNotification) {
|
|
213
|
+
checks.push({
|
|
214
|
+
code: 'WEAVER_NO_NOTIFICATION',
|
|
215
|
+
severity: 'info',
|
|
216
|
+
message: 'Workflow has side-effect nodes but no notification or reporting node. Consider adding one for observability.',
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return checks;
|
|
220
|
+
}
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
// Score calculation
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
const SEVERITY_WEIGHTS = {
|
|
225
|
+
error: 10,
|
|
226
|
+
warning: 3,
|
|
227
|
+
info: 1,
|
|
228
|
+
};
|
|
229
|
+
function calculateScore(checks) {
|
|
230
|
+
if (checks.length === 0)
|
|
231
|
+
return 100;
|
|
232
|
+
let penalty = 0;
|
|
233
|
+
for (const check of checks) {
|
|
234
|
+
penalty += SEVERITY_WEIGHTS[check.severity] ?? 1;
|
|
235
|
+
}
|
|
236
|
+
// Cap at 0
|
|
237
|
+
return Math.max(0, 100 - penalty);
|
|
238
|
+
}
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
// Public API
|
|
241
|
+
// ---------------------------------------------------------------------------
|
|
242
|
+
export function checkDesignQuality(ast) {
|
|
243
|
+
const allCheckers = [
|
|
244
|
+
checkVisualAnnotations,
|
|
245
|
+
checkDescriptiveIds,
|
|
246
|
+
checkFlowDirection,
|
|
247
|
+
checkDescription,
|
|
248
|
+
checkNodeCount,
|
|
249
|
+
checkScopeNesting,
|
|
250
|
+
checkFanInComplexity,
|
|
251
|
+
checkFanOutComplexity,
|
|
252
|
+
checkNotificationPresence,
|
|
253
|
+
];
|
|
254
|
+
const checks = [];
|
|
255
|
+
for (const checker of allCheckers) {
|
|
256
|
+
checks.push(...checker(ast));
|
|
257
|
+
}
|
|
258
|
+
const failed = checks.length;
|
|
259
|
+
// Total possible checks is roughly: instances * 2 (visuals, id) + 4 (globals)
|
|
260
|
+
const totalPossible = ast.instances.length * 2 + 4;
|
|
261
|
+
const passed = Math.max(0, totalPossible - failed);
|
|
262
|
+
return {
|
|
263
|
+
score: calculateScore(checks),
|
|
264
|
+
checks,
|
|
265
|
+
passed,
|
|
266
|
+
failed,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=design-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-checker.js","sourceRoot":"","sources":["../../src/bot/design-checker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { type DesignReport } from './design-checker.js';
|
|
2
|
+
export interface FileValidationResult {
|
|
2
3
|
file: string;
|
|
3
4
|
valid: boolean;
|
|
4
5
|
errors: string[];
|
|
5
6
|
warnings: string[];
|
|
6
|
-
|
|
7
|
+
designReport?: DesignReport;
|
|
8
|
+
}
|
|
9
|
+
export declare function validateFiles(files: string[], projectDir: string): FileValidationResult[];
|
|
7
10
|
//# sourceMappingURL=file-validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-validator.d.ts","sourceRoot":"","sources":["../../src/bot/file-validator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-validator.d.ts","sourceRoot":"","sources":["../../src/bot/file-validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,GACjB,oBAAoB,EAAE,CAwBxB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { checkDesignQuality } from './design-checker.js';
|
|
2
3
|
export function validateFiles(files, projectDir) {
|
|
3
4
|
const results = [];
|
|
4
5
|
for (const file of files) {
|
|
@@ -8,7 +9,14 @@ export function validateFiles(files, projectDir) {
|
|
|
8
9
|
execFileSync('flow-weaver', ['validate', file], {
|
|
9
10
|
cwd: projectDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 30_000,
|
|
10
11
|
});
|
|
11
|
-
|
|
12
|
+
// Run design quality check on the AST
|
|
13
|
+
const designReport = runDesignCheck(file, projectDir);
|
|
14
|
+
const designWarnings = designReport
|
|
15
|
+
? designReport.checks
|
|
16
|
+
.filter((c) => c.severity === 'warning' || c.severity === 'error')
|
|
17
|
+
.map((c) => `[${c.code}] ${c.message}`)
|
|
18
|
+
: [];
|
|
19
|
+
results.push({ file, valid: true, errors: [], warnings: designWarnings, designReport: designReport ?? undefined });
|
|
12
20
|
}
|
|
13
21
|
catch (err) {
|
|
14
22
|
const msg = err instanceof Error ? err.stderr ?? err.message : String(err);
|
|
@@ -17,4 +25,17 @@ export function validateFiles(files, projectDir) {
|
|
|
17
25
|
}
|
|
18
26
|
return results;
|
|
19
27
|
}
|
|
28
|
+
function runDesignCheck(file, projectDir) {
|
|
29
|
+
try {
|
|
30
|
+
const astJson = execFileSync('flow-weaver', ['parse', file, '--format', 'json'], {
|
|
31
|
+
cwd: projectDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 30_000,
|
|
32
|
+
});
|
|
33
|
+
const ast = JSON.parse(astJson);
|
|
34
|
+
return checkDesignQuality(ast);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// If parse fails, skip design checks (validation already caught the error)
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
20
41
|
//# sourceMappingURL=file-validator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-validator.js","sourceRoot":"","sources":["../../src/bot/file-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"file-validator.js","sourceRoot":"","sources":["../../src/bot/file-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAqB,MAAM,qBAAqB,CAAC;AAU5E,MAAM,UAAU,aAAa,CAC3B,KAAe,EACf,UAAkB;IAElB,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QACpC,IAAI,CAAC;YACH,YAAY,CAAC,aAAa,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE;gBAC9C,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM;aACrF,CAAC,CAAC;YACH,sCAAsC;YACtC,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACtD,MAAM,cAAc,GAAG,YAAY;gBACjC,CAAC,CAAC,YAAY,CAAC,MAAM;qBAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC;qBACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC3C,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,IAAI,SAAS,EAAE,CAAC,CAAC;QACrH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAE,GAA2B,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpG,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,UAAkB;IACtD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE;YAC/E,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM;SACrF,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,2EAA2E;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared prompt helpers for genesis propose and revise steps.
|
|
3
|
+
* Centralises context building so the AI always gets the CLI grammar,
|
|
4
|
+
* operation syntax, and workflow structure it needs to produce valid proposals.
|
|
5
|
+
*/
|
|
6
|
+
import type { GenesisConfig } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Full system prompt with annotation grammar, CLI commands, validation codes,
|
|
9
|
+
* and genesis protocol. Cached after first call.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getGenesisSystemPrompt(config: GenesisConfig, stabilized: boolean, options?: {
|
|
12
|
+
selfEvolveLocked?: boolean;
|
|
13
|
+
graceRemaining?: number;
|
|
14
|
+
}): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Operation format reference with concrete examples.
|
|
17
|
+
* Appended to both propose and revise prompts so the AI knows
|
|
18
|
+
* the exact CLI arg format.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getOperationExamples(targetPath: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Ops context from flow-weaver docs (CLI reference, error codes, etc.).
|
|
23
|
+
* Falls back gracefully if the context module is unavailable.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getOpsContext(): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Gets a text description of the workflow using the describe module.
|
|
28
|
+
* Falls back to reading the raw file if describe isn't available.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getWorkflowDescription(filePath: string): Promise<string>;
|
|
31
|
+
//# sourceMappingURL=genesis-prompt-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genesis-prompt-context.d.ts","sourceRoot":"","sources":["../../src/bot/genesis-prompt-context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,OAAO,EACnB,OAAO,CAAC,EAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,OAAO,CAAC,MAAM,CAAC,CAoCjB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAqC/D;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAYrD;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9E"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared prompt helpers for genesis propose and revise steps.
|
|
3
|
+
* Centralises context building so the AI always gets the CLI grammar,
|
|
4
|
+
* operation syntax, and workflow structure it needs to produce valid proposals.
|
|
5
|
+
*/
|
|
6
|
+
import { buildSystemPrompt } from './system-prompt.js';
|
|
7
|
+
let cachedOpsContext = null;
|
|
8
|
+
/**
|
|
9
|
+
* Full system prompt with annotation grammar, CLI commands, validation codes,
|
|
10
|
+
* and genesis protocol. Cached after first call.
|
|
11
|
+
*/
|
|
12
|
+
export async function getGenesisSystemPrompt(config, stabilized, options) {
|
|
13
|
+
const base = await buildSystemPrompt();
|
|
14
|
+
const stabilizeClause = stabilized
|
|
15
|
+
? '\n\nSTABILIZE MODE: Only removeNode, removeConnection, and implementNode operations are allowed. Do NOT propose addNode or addConnection.'
|
|
16
|
+
: '';
|
|
17
|
+
const selfEvolveClause = config.selfEvolve
|
|
18
|
+
? [
|
|
19
|
+
'',
|
|
20
|
+
'## Self-Evolution',
|
|
21
|
+
`Self-evolution is ENABLED with a budget of ${config.selfEvolveBudget ?? 2} cost units.`,
|
|
22
|
+
'Cost map: selfModifyWorkflow=3, selfModifyNodeType=2, selfModifyModule=2.',
|
|
23
|
+
'Self-modify operations use { file: "relative/path.ts", content: "full file content" } in args.',
|
|
24
|
+
'The file path is relative to the pack root (e.g. "src/workflows/genesis-task.ts").',
|
|
25
|
+
'Content must be the complete replacement file, not a diff.',
|
|
26
|
+
].join('\n')
|
|
27
|
+
: '';
|
|
28
|
+
const lockClause = options?.selfEvolveLocked
|
|
29
|
+
? `\n\nSELF-EVOLUTION LOCKED: A migration is in grace period (${options.graceRemaining} cycles remaining). Do not propose selfModify operations.`
|
|
30
|
+
: '';
|
|
31
|
+
return [
|
|
32
|
+
base,
|
|
33
|
+
'',
|
|
34
|
+
'## Genesis Cycle Config',
|
|
35
|
+
`Intent: ${config.intent}`,
|
|
36
|
+
config.focus.length > 0 ? `Focus areas: ${config.focus.join(', ')}` : '',
|
|
37
|
+
config.constraints.length > 0 ? `Constraints: ${config.constraints.join(', ')}` : '',
|
|
38
|
+
`Budget: ${config.budgetPerCycle} cost units per cycle.`,
|
|
39
|
+
'Cost map: addNode=1, removeNode=1, addConnection=1, removeConnection=1, implementNode=2.',
|
|
40
|
+
stabilizeClause,
|
|
41
|
+
selfEvolveClause,
|
|
42
|
+
lockClause,
|
|
43
|
+
].filter(Boolean).join('\n');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Operation format reference with concrete examples.
|
|
47
|
+
* Appended to both propose and revise prompts so the AI knows
|
|
48
|
+
* the exact CLI arg format.
|
|
49
|
+
*/
|
|
50
|
+
export function getOperationExamples(targetPath) {
|
|
51
|
+
return `## Operation Format
|
|
52
|
+
|
|
53
|
+
Each operation is { type, args, costUnits, rationale }.
|
|
54
|
+
|
|
55
|
+
### addNode
|
|
56
|
+
args: { "nodeId": "myNode", "nodeType": "someFunction", "file": "${targetPath}" }
|
|
57
|
+
|
|
58
|
+
### removeNode
|
|
59
|
+
args: { "nodeId": "myNode", "file": "${targetPath}" }
|
|
60
|
+
|
|
61
|
+
### addConnection
|
|
62
|
+
args: { "from": "sourceNode.portName", "to": "targetNode.portName", "file": "${targetPath}" }
|
|
63
|
+
IMPORTANT: Connection format is "node.port" using a DOT separator. NOT "node:port", NOT "node:portName".
|
|
64
|
+
|
|
65
|
+
### removeConnection
|
|
66
|
+
args: { "from": "sourceNode.portName", "to": "targetNode.portName", "file": "${targetPath}" }
|
|
67
|
+
|
|
68
|
+
### implementNode
|
|
69
|
+
args: { "nodeId": "existingStubNodeId", "file": "${targetPath}" }
|
|
70
|
+
Only works on nodes declared with \`declare function\` (stubs). The nodeId must match an existing stub in the workflow.
|
|
71
|
+
|
|
72
|
+
### selfModifyWorkflow (cost: 3)
|
|
73
|
+
args: { "file": "src/workflows/genesis-task.ts", "content": "// full file content..." }
|
|
74
|
+
Replaces the genesis workflow file. File path is relative to pack root.
|
|
75
|
+
|
|
76
|
+
### selfModifyNodeType (cost: 2)
|
|
77
|
+
args: { "file": "src/node-types/genesis-propose.ts", "content": "// full file content..." }
|
|
78
|
+
Replaces a genesis node type implementation.
|
|
79
|
+
|
|
80
|
+
### selfModifyModule (cost: 2)
|
|
81
|
+
args: { "file": "src/bot/genesis-prompt-context.ts", "content": "// full file content..." }
|
|
82
|
+
Replaces a bot module file.
|
|
83
|
+
|
|
84
|
+
## Response Format
|
|
85
|
+
Return ONLY valid JSON with: { operations: [...], totalCost: number, impactLevel: "COSMETIC"|"MINOR"|"BREAKING"|"CRITICAL", summary: string, rationale: string }
|
|
86
|
+
No markdown, no code fences, no explanation outside the JSON.`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Ops context from flow-weaver docs (CLI reference, error codes, etc.).
|
|
90
|
+
* Falls back gracefully if the context module is unavailable.
|
|
91
|
+
*/
|
|
92
|
+
export async function getOpsContext() {
|
|
93
|
+
if (cachedOpsContext)
|
|
94
|
+
return cachedOpsContext;
|
|
95
|
+
try {
|
|
96
|
+
const { buildContext } = await import('@synergenius/flow-weaver/context');
|
|
97
|
+
const result = buildContext({ preset: 'ops', includeGrammar: false });
|
|
98
|
+
cachedOpsContext = result.content;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
cachedOpsContext = '(ops context unavailable)';
|
|
102
|
+
}
|
|
103
|
+
return cachedOpsContext;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Gets a text description of the workflow using the describe module.
|
|
107
|
+
* Falls back to reading the raw file if describe isn't available.
|
|
108
|
+
*/
|
|
109
|
+
export async function getWorkflowDescription(filePath) {
|
|
110
|
+
try {
|
|
111
|
+
const { parseWorkflow } = await import('@synergenius/flow-weaver/api');
|
|
112
|
+
const { describeWorkflow, formatTextOutput } = await import('@synergenius/flow-weaver/describe');
|
|
113
|
+
const result = await parseWorkflow(filePath);
|
|
114
|
+
const output = describeWorkflow(result.ast);
|
|
115
|
+
return formatTextOutput(result.ast, output);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return '(workflow description unavailable)';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=genesis-prompt-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genesis-prompt-context.js","sourceRoot":"","sources":["../../src/bot/genesis-prompt-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GenesisConfig, GenesisHistory, GenesisCycleRecord, GenesisFingerprint } from './types.js';
|
|
1
|
+
import type { GenesisConfig, GenesisHistory, GenesisCycleRecord, GenesisFingerprint, EscrowToken, GenesisSelfMigrationRecord } from './types.js';
|
|
2
2
|
export declare class GenesisStore {
|
|
3
3
|
private genesisDir;
|
|
4
4
|
constructor(projectDir: string);
|
|
@@ -14,5 +14,15 @@ export declare class GenesisStore {
|
|
|
14
14
|
getRecentOutcomes(count: number): string[];
|
|
15
15
|
static newCycleId(): string;
|
|
16
16
|
static hashConfig(config: GenesisConfig): string;
|
|
17
|
+
ensureEscrowDirs(): void;
|
|
18
|
+
loadEscrowToken(): EscrowToken | null;
|
|
19
|
+
saveEscrowToken(token: EscrowToken): void;
|
|
20
|
+
clearEscrow(): void;
|
|
21
|
+
getEscrowStagedPath(relativePath: string): string;
|
|
22
|
+
getEscrowBackupPath(relativePath: string): string;
|
|
23
|
+
loadSelfHistory(): GenesisSelfMigrationRecord[];
|
|
24
|
+
appendSelfMigration(record: GenesisSelfMigrationRecord): void;
|
|
25
|
+
getSelfFailureCount(): number;
|
|
26
|
+
static hashFile(filePath: string): string;
|
|
17
27
|
}
|
|
18
28
|
//# sourceMappingURL=genesis-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genesis-store.d.ts","sourceRoot":"","sources":["../../src/bot/genesis-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"genesis-store.d.ts","sourceRoot":"","sources":["../../src/bot/genesis-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAajJ,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,EAAE,MAAM;IAI9B,UAAU,IAAI,IAAI;IAIlB,UAAU,IAAI,aAAa;IAW3B,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAKvC,WAAW,IAAI,cAAc;IAQ7B,WAAW,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAO5C,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAOtD,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQjD,eAAe,CAAC,WAAW,EAAE,kBAAkB,GAAG,IAAI;IAKtD,kBAAkB,IAAI,kBAAkB,GAAG,IAAI;IAU/C,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAK1C,MAAM,CAAC,UAAU,IAAI,MAAM;IAI3B,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAMhD,gBAAgB,IAAI,IAAI;IAKxB,eAAe,IAAI,WAAW,GAAG,IAAI;IAUrC,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IASzC,WAAW,IAAI,IAAI;IAOnB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAIjD,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAMjD,eAAe,IAAI,0BAA0B,EAAE;IAU/C,mBAAmB,CAAC,MAAM,EAAE,0BAA0B,GAAG,IAAI;IAW7D,mBAAmB,IAAI,MAAM;IAU7B,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAI1C"}
|
|
@@ -85,5 +85,70 @@ export class GenesisStore {
|
|
|
85
85
|
static hashConfig(config) {
|
|
86
86
|
return crypto.createHash('sha256').update(JSON.stringify(config)).digest('hex').slice(0, 12);
|
|
87
87
|
}
|
|
88
|
+
// --- Escrow ---
|
|
89
|
+
ensureEscrowDirs() {
|
|
90
|
+
fs.mkdirSync(path.join(this.genesisDir, 'escrow', 'staged'), { recursive: true });
|
|
91
|
+
fs.mkdirSync(path.join(this.genesisDir, 'escrow', 'backup'), { recursive: true });
|
|
92
|
+
}
|
|
93
|
+
loadEscrowToken() {
|
|
94
|
+
const tokenPath = path.join(this.genesisDir, 'escrow', 'token.json');
|
|
95
|
+
if (!fs.existsSync(tokenPath))
|
|
96
|
+
return null;
|
|
97
|
+
try {
|
|
98
|
+
return JSON.parse(fs.readFileSync(tokenPath, 'utf-8'));
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
saveEscrowToken(token) {
|
|
105
|
+
this.ensureEscrowDirs();
|
|
106
|
+
fs.writeFileSync(path.join(this.genesisDir, 'escrow', 'token.json'), JSON.stringify(token, null, 2), 'utf-8');
|
|
107
|
+
}
|
|
108
|
+
clearEscrow() {
|
|
109
|
+
const escrowDir = path.join(this.genesisDir, 'escrow');
|
|
110
|
+
if (fs.existsSync(escrowDir)) {
|
|
111
|
+
fs.rmSync(escrowDir, { recursive: true, force: true });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
getEscrowStagedPath(relativePath) {
|
|
115
|
+
return path.join(this.genesisDir, 'escrow', 'staged', relativePath);
|
|
116
|
+
}
|
|
117
|
+
getEscrowBackupPath(relativePath) {
|
|
118
|
+
return path.join(this.genesisDir, 'escrow', 'backup', relativePath);
|
|
119
|
+
}
|
|
120
|
+
// --- Self-evolution history ---
|
|
121
|
+
loadSelfHistory() {
|
|
122
|
+
const histPath = path.join(this.genesisDir, 'self-history.json');
|
|
123
|
+
if (!fs.existsSync(histPath))
|
|
124
|
+
return [];
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(fs.readFileSync(histPath, 'utf-8'));
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
appendSelfMigration(record) {
|
|
133
|
+
const records = this.loadSelfHistory();
|
|
134
|
+
records.push(record);
|
|
135
|
+
this.ensureDirs();
|
|
136
|
+
fs.writeFileSync(path.join(this.genesisDir, 'self-history.json'), JSON.stringify(records, null, 2), 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
getSelfFailureCount() {
|
|
139
|
+
const records = this.loadSelfHistory();
|
|
140
|
+
let count = 0;
|
|
141
|
+
for (let i = records.length - 1; i >= 0; i--) {
|
|
142
|
+
if (records[i].outcome === 'rolled-back')
|
|
143
|
+
count++;
|
|
144
|
+
else
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
return count;
|
|
148
|
+
}
|
|
149
|
+
static hashFile(filePath) {
|
|
150
|
+
const content = fs.readFileSync(filePath);
|
|
151
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
152
|
+
}
|
|
88
153
|
}
|
|
89
154
|
//# sourceMappingURL=genesis-store.js.map
|