@wowok/agent-mcp 2.5.1 → 2.5.3

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 (107) hide show
  1. package/dist/index.js +46 -6
  2. package/dist/knowledge/guard-design-patterns.js +104 -1
  3. package/dist/knowledge/guard-ledger.js +3 -3
  4. package/dist/knowledge/guard-lint.js +3 -3
  5. package/dist/knowledge/guard-risk.js +23 -15
  6. package/dist/knowledge/guard-templates.js +174 -2
  7. package/dist/knowledge/guard-translation.js +3 -3
  8. package/dist/knowledge/index.d.ts +3 -0
  9. package/dist/knowledge/index.js +9 -0
  10. package/dist/knowledge/machine-context.d.ts +1 -1
  11. package/dist/knowledge/machine-context.js +21 -0
  12. package/dist/knowledge/machine-ledger.d.ts +1 -0
  13. package/dist/knowledge/machine-ledger.js +31 -11
  14. package/dist/knowledge/machine-templates.js +32 -78
  15. package/dist/knowledge/mcp-schema-audit.js +3 -2
  16. package/dist/knowledge/overrides-loader.d.ts +13 -0
  17. package/dist/knowledge/overrides-loader.js +67 -0
  18. package/dist/knowledge/payment-risk.d.ts +4 -0
  19. package/dist/knowledge/payment-risk.js +67 -0
  20. package/dist/knowledge/repository-confirm.d.ts +4 -0
  21. package/dist/knowledge/repository-confirm.js +44 -0
  22. package/dist/knowledge/repository-risk.d.ts +8 -2
  23. package/dist/knowledge/repository-risk.js +61 -0
  24. package/dist/knowledge/repository-translation.js +23 -0
  25. package/dist/knowledge/scenario-modes.js +22 -5
  26. package/dist/knowledge/service-templates.js +38 -0
  27. package/dist/knowledge/treasury-templates.js +42 -0
  28. package/dist/loop-engineering/context-collect.d.ts +7 -0
  29. package/dist/loop-engineering/context-collect.js +83 -0
  30. package/dist/loop-engineering/improve.d.ts +29 -0
  31. package/dist/loop-engineering/improve.js +178 -0
  32. package/dist/project/business-puzzle.d.ts +1 -0
  33. package/dist/project/business-puzzle.js +11 -0
  34. package/dist/project/context-assembly.d.ts +16 -0
  35. package/dist/project/context-assembly.js +130 -0
  36. package/dist/project/deployment-doc.d.ts +126 -0
  37. package/dist/project/deployment-doc.js +632 -0
  38. package/dist/project/index.d.ts +25 -0
  39. package/dist/project/index.js +78 -0
  40. package/dist/project/migration.d.ts +22 -0
  41. package/dist/project/migration.js +125 -0
  42. package/dist/project/project-store.d.ts +110 -0
  43. package/dist/project/project-store.js +425 -0
  44. package/dist/project/risk-aggregator.d.ts +7 -0
  45. package/dist/project/risk-aggregator.js +15 -0
  46. package/dist/project/rollback-policy.d.ts +45 -0
  47. package/dist/project/rollback-policy.js +290 -0
  48. package/dist/project/stage-gate.d.ts +49 -0
  49. package/dist/project/stage-gate.js +310 -0
  50. package/dist/schema/call/allocation.d.ts +5 -0
  51. package/dist/schema/call/arbitration.d.ts +5 -0
  52. package/dist/schema/call/base.d.ts +3 -0
  53. package/dist/schema/call/base.js +3 -2
  54. package/dist/schema/call/bridge.d.ts +24 -0
  55. package/dist/schema/call/contact.d.ts +5 -0
  56. package/dist/schema/call/demand.d.ts +5 -0
  57. package/dist/schema/call/guard.d.ts +15 -0
  58. package/dist/schema/call/machine.d.ts +10 -0
  59. package/dist/schema/call/order.d.ts +5 -0
  60. package/dist/schema/call/payment.d.ts +5 -0
  61. package/dist/schema/call/permission.d.ts +5 -0
  62. package/dist/schema/call/personal.d.ts +5 -0
  63. package/dist/schema/call/progress.d.ts +5 -0
  64. package/dist/schema/call/proof.d.ts +10 -0
  65. package/dist/schema/call/repository.d.ts +5 -0
  66. package/dist/schema/call/reward.d.ts +5 -0
  67. package/dist/schema/call/service.d.ts +5 -0
  68. package/dist/schema/call/treasury.d.ts +5 -0
  69. package/dist/schema/operations.d.ts +210 -0
  70. package/dist/schema/operations.js +24 -0
  71. package/dist/schema/project/index.d.ts +2798 -85
  72. package/dist/schema/project/index.js +667 -2
  73. package/dist/schema/query/index.d.ts +601 -0
  74. package/dist/schema/query/index.js +61 -0
  75. package/dist/schemas/bridge_operation.schema.json +4 -0
  76. package/dist/schemas/guard2file.schema.json +4 -0
  77. package/dist/schemas/index.json +1 -1
  78. package/dist/schemas/machineNode2file.schema.json +4 -0
  79. package/dist/schemas/onchain_operations.schema.json +20 -0
  80. package/dist/schemas/onchain_operations_allocation.schema.json +4 -0
  81. package/dist/schemas/onchain_operations_arbitration.schema.json +4 -0
  82. package/dist/schemas/onchain_operations_contact.schema.json +4 -0
  83. package/dist/schemas/onchain_operations_demand.schema.json +4 -0
  84. package/dist/schemas/onchain_operations_gen_passport.schema.json +8 -0
  85. package/dist/schemas/onchain_operations_gen_proof.schema.json +8 -0
  86. package/dist/schemas/onchain_operations_guard.schema.json +4 -577
  87. package/dist/schemas/onchain_operations_machine.schema.json +4 -0
  88. package/dist/schemas/onchain_operations_order.schema.json +4 -0
  89. package/dist/schemas/onchain_operations_payment.schema.json +4 -0
  90. package/dist/schemas/onchain_operations_permission.schema.json +4 -0
  91. package/dist/schemas/onchain_operations_personal.schema.json +4 -0
  92. package/dist/schemas/onchain_operations_progress.schema.json +4 -0
  93. package/dist/schemas/onchain_operations_proof.schema.json +4 -0
  94. package/dist/schemas/onchain_operations_repository.schema.json +4 -0
  95. package/dist/schemas/onchain_operations_reward.schema.json +4 -0
  96. package/dist/schemas/onchain_operations_service.schema.json +4 -0
  97. package/dist/schemas/onchain_operations_treasury.schema.json +4 -0
  98. package/dist/schemas/project_operation.output.json +1955 -0
  99. package/dist/schemas/project_operation.schema.json +133 -2
  100. package/dist/schemas/query_toolkit.output.json +407 -1
  101. package/dist/schemas/query_toolkit.schema.json +132 -0
  102. package/dist/tools/handlers/project.js +788 -2
  103. package/dist/tools/handlers/query.js +38 -2
  104. package/dist/tools/index.js +346 -37
  105. package/dist/tools/wrap.js +61 -7
  106. package/package.json +2 -2
  107. package/dist/schemas/onchain_operations.output.json +0 -2819
@@ -0,0 +1,425 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, copyFileSync, statSync, appendFileSync, } from "fs";
2
+ import { dirname, join } from "path";
3
+ import { homedir } from "os";
4
+ export const CURRENT_SCHEMA_VERSION = "1.0.0";
5
+ export function projectsRootDir() {
6
+ const base = process.env.WOWOK_CONFIG_DIR
7
+ ? process.env.WOWOK_CONFIG_DIR
8
+ : join(homedir(), ".wowok");
9
+ return join(base, "projects");
10
+ }
11
+ export function projectDir(prefix, version) {
12
+ return join(projectsRootDir(), `${prefix}_${version}`);
13
+ }
14
+ export function deploymentDir(prefix, version) {
15
+ return join(projectDir(prefix, version), "deployment");
16
+ }
17
+ function manifestPath(prefix, version) {
18
+ return join(projectDir(prefix, version), "manifest.json");
19
+ }
20
+ function stageStatePath(prefix, version) {
21
+ return join(projectDir(prefix, version), "stage.json");
22
+ }
23
+ function auditLogPath(prefix, version) {
24
+ return join(projectDir(prefix, version), "audit.jsonl");
25
+ }
26
+ export function ensureProjectDir(prefix, version) {
27
+ const dir = projectDir(prefix, version);
28
+ if (!existsSync(dir)) {
29
+ mkdirSync(dir, { recursive: true });
30
+ }
31
+ return dir;
32
+ }
33
+ export function initProject(prefix, version, options = {}) {
34
+ ensureProjectDir(prefix, version);
35
+ const now = new Date().toISOString();
36
+ const manifest = {
37
+ schema_version: CURRENT_SCHEMA_VERSION,
38
+ mcp_version: options.mcpVersion ?? "unknown",
39
+ prefix,
40
+ version,
41
+ created_at: now,
42
+ updated_at: now,
43
+ forked_from: options.forkedFrom,
44
+ };
45
+ writeFileSync(manifestPath(prefix, version), JSON.stringify(manifest, null, 2), "utf-8");
46
+ const stageState = {
47
+ stage: 1,
48
+ updated_at: Date.now(),
49
+ stage_meta: {
50
+ 1: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
51
+ 2: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
52
+ 3: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
53
+ 4: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
54
+ 5: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
55
+ },
56
+ has_published_object: false,
57
+ archived: false,
58
+ };
59
+ saveStageState(prefix, version, stageState);
60
+ appendAudit(prefix, version, {
61
+ timestamp: now,
62
+ event: "stage_commit",
63
+ stage: 1,
64
+ reason: `project initialized${options.forkedFrom ? ` (forked from ${options.forkedFrom})` : ""}`,
65
+ affected_files: ["manifest.json", "stage.json"],
66
+ });
67
+ return manifest;
68
+ }
69
+ export function loadManifest(prefix, version) {
70
+ const p = manifestPath(prefix, version);
71
+ if (!existsSync(p)) {
72
+ throw new Error(`project not initialized: ${prefix}_${version} (missing manifest.json)`);
73
+ }
74
+ const raw = readFileSync(p, "utf-8");
75
+ return JSON.parse(raw);
76
+ }
77
+ export function saveManifest(prefix, version, manifest) {
78
+ manifest.updated_at = new Date().toISOString();
79
+ writeFileSync(manifestPath(prefix, version), JSON.stringify(manifest, null, 2), "utf-8");
80
+ }
81
+ export function loadStageState(prefix, version) {
82
+ const p = stageStatePath(prefix, version);
83
+ if (!existsSync(p))
84
+ return undefined;
85
+ const raw = readFileSync(p, "utf-8");
86
+ return JSON.parse(raw);
87
+ }
88
+ export function saveStageState(prefix, version, state) {
89
+ state.updated_at = Date.now();
90
+ ensureProjectDir(prefix, version);
91
+ writeFileSync(stageStatePath(prefix, version), JSON.stringify(state, null, 2), "utf-8");
92
+ }
93
+ export function saveProjectFile(prefix, version, relPath, data) {
94
+ const abs = join(projectDir(prefix, version), relPath);
95
+ mkdirSync(dirname(abs), { recursive: true });
96
+ writeFileSync(abs, JSON.stringify(data, null, 2), "utf-8");
97
+ return abs;
98
+ }
99
+ export function loadProjectFile(prefix, version, relPath) {
100
+ const abs = join(projectDir(prefix, version), relPath);
101
+ if (!existsSync(abs))
102
+ return undefined;
103
+ const raw = readFileSync(abs, "utf-8");
104
+ return JSON.parse(raw);
105
+ }
106
+ export function saveProjectMarkdown(prefix, version, relPath, markdown) {
107
+ const abs = join(projectDir(prefix, version), relPath);
108
+ mkdirSync(dirname(abs), { recursive: true });
109
+ writeFileSync(abs, markdown, "utf-8");
110
+ return abs;
111
+ }
112
+ export function appendJsonl(prefix, version, relPath, record) {
113
+ const abs = join(projectDir(prefix, version), relPath);
114
+ ensureProjectDir(prefix, version);
115
+ mkdirSync(dirname(abs), { recursive: true });
116
+ appendFileSync(abs, JSON.stringify(record) + "\n", "utf-8");
117
+ return abs;
118
+ }
119
+ export function appendAudit(prefix, version, record) {
120
+ appendJsonl(prefix, version, "audit.jsonl", record);
121
+ }
122
+ export function readAuditLog(prefix, version) {
123
+ const abs = auditLogPath(prefix, version);
124
+ if (!existsSync(abs))
125
+ return [];
126
+ const raw = readFileSync(abs, "utf-8");
127
+ return raw
128
+ .split("\n")
129
+ .filter((l) => l.trim().length > 0)
130
+ .map((l) => JSON.parse(l));
131
+ }
132
+ export function parseProjectDirName(dirName) {
133
+ const m = dirName.match(/^(.+)_v(\d+)$/);
134
+ if (!m)
135
+ return undefined;
136
+ return { prefix: m[1], version: `v${m[2]}` };
137
+ }
138
+ export function listLocalProjects() {
139
+ const root = projectsRootDir();
140
+ if (!existsSync(root))
141
+ return [];
142
+ const entries = readdirSync(root, { withFileTypes: true });
143
+ const out = [];
144
+ for (const e of entries) {
145
+ if (!e.isDirectory())
146
+ continue;
147
+ const parsed = parseProjectDirName(e.name);
148
+ if (!parsed)
149
+ continue;
150
+ const fullPath = join(root, e.name);
151
+ const manifestFile = join(fullPath, "manifest.json");
152
+ const stageFile = join(fullPath, "stage.json");
153
+ let initialized = false;
154
+ let archived = false;
155
+ let needsMigration = false;
156
+ let forkedFrom;
157
+ if (existsSync(manifestFile)) {
158
+ initialized = true;
159
+ try {
160
+ const m = JSON.parse(readFileSync(manifestFile, "utf-8"));
161
+ needsMigration = m.schema_version !== CURRENT_SCHEMA_VERSION;
162
+ forkedFrom = m.forked_from;
163
+ }
164
+ catch {
165
+ }
166
+ }
167
+ if (existsSync(stageFile)) {
168
+ try {
169
+ const s = JSON.parse(readFileSync(stageFile, "utf-8"));
170
+ archived = s.archived;
171
+ }
172
+ catch {
173
+ }
174
+ }
175
+ let mtime = 0;
176
+ try {
177
+ mtime = statSync(fullPath).mtimeMs;
178
+ }
179
+ catch {
180
+ }
181
+ out.push({
182
+ dir_name: e.name,
183
+ prefix: parsed.prefix,
184
+ version: parsed.version,
185
+ path: fullPath,
186
+ initialized,
187
+ archived,
188
+ needs_migration: needsMigration,
189
+ forked_from: forkedFrom,
190
+ mtime,
191
+ });
192
+ }
193
+ return out.sort((a, b) => b.mtime - a.mtime);
194
+ }
195
+ export function projectExists(prefix, version) {
196
+ return existsSync(manifestPath(prefix, version));
197
+ }
198
+ export function forkProject(srcPrefix, srcVersion, opts) {
199
+ if (!projectExists(srcPrefix, srcVersion)) {
200
+ throw new Error(`source project not found: ${srcPrefix}_${srcVersion}`);
201
+ }
202
+ const newPrefix = opts.newPrefix ?? srcPrefix;
203
+ if (opts.newVersion === srcVersion && newPrefix === srcPrefix) {
204
+ throw new Error("fork target must differ from source (set newVersion or newPrefix)");
205
+ }
206
+ ensureProjectDir(newPrefix, opts.newVersion);
207
+ const srcDir = projectDir(srcPrefix, srcVersion);
208
+ const dstDir = projectDir(newPrefix, opts.newVersion);
209
+ const copiedFiles = [];
210
+ function walkDir(relBase) {
211
+ const absBase = join(srcDir, relBase);
212
+ if (!existsSync(absBase))
213
+ return;
214
+ const items = readdirSync(absBase, { withFileTypes: true });
215
+ for (const item of items) {
216
+ const rel = relBase ? join(relBase, item.name) : item.name;
217
+ const srcAbs = join(srcDir, rel);
218
+ const dstAbs = join(dstDir, rel);
219
+ if (item.isDirectory()) {
220
+ mkdirSync(dstAbs, { recursive: true });
221
+ walkDir(rel);
222
+ }
223
+ else if (item.isFile()) {
224
+ if (rel === "stage.json" || rel === "audit.jsonl")
225
+ continue;
226
+ mkdirSync(dirname(dstAbs), { recursive: true });
227
+ copyFileSync(srcAbs, dstAbs);
228
+ copiedFiles.push(rel);
229
+ }
230
+ }
231
+ }
232
+ walkDir("");
233
+ const now = new Date().toISOString();
234
+ const manifest = {
235
+ schema_version: CURRENT_SCHEMA_VERSION,
236
+ mcp_version: opts.mcpVersion ?? "unknown",
237
+ prefix: newPrefix,
238
+ version: opts.newVersion,
239
+ created_at: now,
240
+ updated_at: now,
241
+ forked_from: srcDir,
242
+ };
243
+ writeFileSync(manifestPath(newPrefix, opts.newVersion), JSON.stringify(manifest, null, 2), "utf-8");
244
+ const stageState = {
245
+ stage: 1,
246
+ updated_at: Date.now(),
247
+ stage_meta: {
248
+ 1: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
249
+ 2: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
250
+ 3: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
251
+ 4: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
252
+ 5: { committed: false, gate_passed: false, blocking_issues: [], completion: 0 },
253
+ },
254
+ has_published_object: false,
255
+ archived: false,
256
+ };
257
+ saveStageState(newPrefix, opts.newVersion, stageState);
258
+ appendAudit(newPrefix, opts.newVersion, {
259
+ timestamp: now,
260
+ event: "fork_created",
261
+ reason: `forked from ${srcPrefix}_${srcVersion}; objects must be re-created (project isolation §3.0)`,
262
+ affected_files: ["manifest.json", "stage.json"],
263
+ });
264
+ const srcStage = loadStageState(srcPrefix, srcVersion);
265
+ if (srcStage) {
266
+ srcStage.archived = true;
267
+ saveStageState(srcPrefix, srcVersion, srcStage);
268
+ appendAudit(srcPrefix, srcVersion, {
269
+ timestamp: now,
270
+ event: "stage_commit",
271
+ reason: `archived after fork to ${newPrefix}_${opts.newVersion}`,
272
+ affected_files: ["stage.json"],
273
+ });
274
+ }
275
+ return {
276
+ new_prefix: newPrefix,
277
+ new_version: opts.newVersion,
278
+ new_path: dstDir,
279
+ forked_from: srcDir,
280
+ copied_files: copiedFiles,
281
+ };
282
+ }
283
+ export function listProjectFiles(prefix, version) {
284
+ const dir = projectDir(prefix, version);
285
+ if (!existsSync(dir))
286
+ return [];
287
+ const out = [];
288
+ function walk(relBase) {
289
+ const absBase = join(dir, relBase);
290
+ const items = readdirSync(absBase, { withFileTypes: true });
291
+ for (const item of items) {
292
+ const rel = relBase ? join(relBase, item.name) : item.name;
293
+ const abs = join(dir, rel);
294
+ if (item.isDirectory()) {
295
+ walk(rel);
296
+ }
297
+ else if (item.isFile()) {
298
+ let stat;
299
+ try {
300
+ stat = statSync(abs);
301
+ }
302
+ catch {
303
+ continue;
304
+ }
305
+ let kind = "other";
306
+ if (abs.endsWith(".json"))
307
+ kind = "json";
308
+ else if (abs.endsWith(".md"))
309
+ kind = "markdown";
310
+ else if (abs.endsWith(".jsonl"))
311
+ kind = "jsonl";
312
+ out.push({
313
+ path: rel,
314
+ abs_path: abs,
315
+ size: stat.size,
316
+ mtime: stat.mtimeMs,
317
+ kind,
318
+ });
319
+ }
320
+ }
321
+ }
322
+ walk("");
323
+ return out.sort((a, b) => a.path.localeCompare(b.path));
324
+ }
325
+ export function readProjectFile(prefix, version, relPath) {
326
+ const abs = join(projectDir(prefix, version), relPath);
327
+ if (!existsSync(abs))
328
+ return undefined;
329
+ return readFileSync(abs, "utf-8");
330
+ }
331
+ export function commitStage(prefix, version, stage, options = {}) {
332
+ const state = loadStageState(prefix, version);
333
+ if (!state) {
334
+ throw new Error(`project not initialized: ${prefix}_${version}`);
335
+ }
336
+ const gatePassed = options.gatePassed ?? false;
337
+ state.stage_meta[stage] = {
338
+ committed: true,
339
+ committed_at: Date.now(),
340
+ gate_passed: gatePassed,
341
+ blocking_issues: options.blockingIssues ?? [],
342
+ completion: options.completion ?? (gatePassed ? 100 : 0),
343
+ };
344
+ if (stage < 5 && gatePassed) {
345
+ state.stage = (stage + 1);
346
+ }
347
+ saveStageState(prefix, version, state);
348
+ appendAudit(prefix, version, {
349
+ timestamp: new Date().toISOString(),
350
+ event: "stage_commit",
351
+ stage,
352
+ reason: options.reason ?? `stage ${stage} committed`,
353
+ affected_files: ["stage.json"],
354
+ user_confirmed: options.userConfirmed,
355
+ });
356
+ return state;
357
+ }
358
+ export function rollbackStage(prefix, version, toStage, options = {}) {
359
+ const state = loadStageState(prefix, version);
360
+ if (!state) {
361
+ throw new Error(`project not initialized: ${prefix}_${version}`);
362
+ }
363
+ if (state.has_published_object) {
364
+ throw new Error(`cannot rollback: project has published objects — must fork new version (§3.3)`);
365
+ }
366
+ const oldStage = state.stage;
367
+ for (let s = toStage + 1; s <= 5; s++) {
368
+ state.stage_meta[s] = {
369
+ committed: false,
370
+ gate_passed: false,
371
+ blocking_issues: [],
372
+ completion: 0,
373
+ };
374
+ }
375
+ state.stage = toStage;
376
+ saveStageState(prefix, version, state);
377
+ appendAudit(prefix, version, {
378
+ timestamp: new Date().toISOString(),
379
+ event: "stage_rollback",
380
+ stage: toStage,
381
+ reason: options.reason ?? `rollback from stage ${oldStage} to ${toStage}`,
382
+ affected_files: options.affectedFiles ?? ["stage.json"],
383
+ });
384
+ return state;
385
+ }
386
+ export function markObjectPublished(prefix, version, objectName) {
387
+ const state = loadStageState(prefix, version);
388
+ if (!state)
389
+ return;
390
+ if (state.has_published_object)
391
+ return;
392
+ state.has_published_object = true;
393
+ saveStageState(prefix, version, state);
394
+ appendAudit(prefix, version, {
395
+ timestamp: new Date().toISOString(),
396
+ event: "object_published",
397
+ stage: 5,
398
+ reason: `object published: ${objectName} — rollback now requires fork (§3.3)`,
399
+ affected_files: ["stage.json"],
400
+ });
401
+ }
402
+ export function getLocalSyncStatus(prefix, version) {
403
+ const exists = projectExists(prefix, version);
404
+ if (!exists) {
405
+ return { local_exists: false, initialized: false, needs_migration: false, archived: false };
406
+ }
407
+ let initialized = true;
408
+ let needsMigration = false;
409
+ let archived = false;
410
+ try {
411
+ const m = loadManifest(prefix, version);
412
+ needsMigration = m.schema_version !== CURRENT_SCHEMA_VERSION;
413
+ }
414
+ catch {
415
+ initialized = false;
416
+ }
417
+ try {
418
+ const s = loadStageState(prefix, version);
419
+ if (s)
420
+ archived = s.archived;
421
+ }
422
+ catch {
423
+ }
424
+ return { local_exists: true, initialized, needs_migration: needsMigration, archived };
425
+ }
@@ -40,6 +40,13 @@ export interface RiskAggregationResult {
40
40
  entry_id: string;
41
41
  }>;
42
42
  calibrated_at: number;
43
+ fix_suggestions_grouped?: Record<string, Array<{
44
+ risk_rule_id: string;
45
+ severity: RiskSeverity;
46
+ message: string;
47
+ fix_suggestion: string;
48
+ entry_id: string;
49
+ }>>;
43
50
  warnings: string[];
44
51
  }
45
52
  export declare function aggregateProjectRisks(input: RiskAggregationInput): RiskAggregationResult;
@@ -179,6 +179,20 @@ export function aggregateProjectRisks(input) {
179
179
  entry_id: f.entry_id,
180
180
  }));
181
181
  }
182
+ const fixSuggestionsGrouped = {};
183
+ for (const finding of findings) {
184
+ const key = finding.object_type;
185
+ if (!fixSuggestionsGrouped[key]) {
186
+ fixSuggestionsGrouped[key] = [];
187
+ }
188
+ fixSuggestionsGrouped[key].push({
189
+ risk_rule_id: finding.risk_rule_id,
190
+ severity: finding.severity,
191
+ message: finding.message,
192
+ fix_suggestion: finding.fix_suggestion,
193
+ entry_id: finding.entry_id,
194
+ });
195
+ }
182
196
  return {
183
197
  namespace: {
184
198
  prefix: input.project_prefix ?? "",
@@ -190,6 +204,7 @@ export function aggregateProjectRisks(input) {
190
204
  status,
191
205
  pending_confirmations,
192
206
  calibrated_at: Date.now(),
207
+ fix_suggestions_grouped: fixSuggestionsGrouped,
193
208
  warnings,
194
209
  };
195
210
  }
@@ -0,0 +1,45 @@
1
+ import { type ProjectStage, type StageState } from "./project-store.js";
2
+ export type ObjectLifecycleState = "created" | "referenced" | "published" | "bound";
3
+ export type StructReversibility = "reversible" | "limited" | "immutable";
4
+ export type GasImpact = "low" | "medium" | "high" | "none";
5
+ export interface ReversibilityEntry {
6
+ object_type: string;
7
+ lifecycle_state: ObjectLifecycleState;
8
+ struct_reversible: StructReversibility;
9
+ behavior_reversible: boolean;
10
+ gas_impact: GasImpact;
11
+ explanation: string;
12
+ }
13
+ export declare const REVERSIBILITY_MATRIX: ReversibilityEntry[];
14
+ export declare function queryReversibility(objectType: string, lifecycleState: ObjectLifecycleState): ReversibilityEntry | undefined;
15
+ export declare function getReversibilityForType(objectType: string): ReversibilityEntry[];
16
+ export type IterationStrategy = "in_place" | "fork";
17
+ export interface IterationRecommendation {
18
+ strategy: IterationStrategy;
19
+ reason: string;
20
+ fork_to_version?: string;
21
+ published_objects?: string[];
22
+ }
23
+ export declare function recommendIterationStrategy(prefix: string, version: string, currentStage?: ProjectStage): IterationRecommendation;
24
+ export interface RollbackPolicyResult {
25
+ allowed: boolean;
26
+ target_stage: ProjectStage;
27
+ current_stage: ProjectStage;
28
+ block_reason?: string;
29
+ files_to_clean: string[];
30
+ warnings: string[];
31
+ iteration_strategy: IterationRecommendation;
32
+ }
33
+ export declare function evaluateRollbackPolicy(prefix: string, version: string, targetStage: ProjectStage): RollbackPolicyResult;
34
+ export interface RollbackResult {
35
+ success: boolean;
36
+ target_stage: ProjectStage;
37
+ previous_stage: ProjectStage;
38
+ files_to_clean: string[];
39
+ files_cleaned: string[];
40
+ stage_state: StageState;
41
+ warnings: string[];
42
+ iteration_strategy: IterationRecommendation;
43
+ message: string;
44
+ }
45
+ export declare function rollbackStageWithPolicy(prefix: string, version: string, targetStage: ProjectStage, reason?: string): RollbackResult;