chainlesschain 0.152.0 → 0.156.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +52 -3
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +201 -0
  4. package/src/commands/agent.js +1250 -0
  5. package/src/commands/chat.js +605 -0
  6. package/src/commands/cli-anything.js +426 -0
  7. package/src/commands/compliance.js +412 -0
  8. package/src/commands/config.js +213 -0
  9. package/src/commands/cowork.js +1463 -0
  10. package/src/commands/crosschain.js +203 -0
  11. package/src/commands/dao.js +203 -0
  12. package/src/commands/economy.js +199 -0
  13. package/src/commands/encrypt.js +201 -0
  14. package/src/commands/evolution.js +199 -0
  15. package/src/commands/evomap.js +625 -0
  16. package/src/commands/hmemory.js +203 -0
  17. package/src/commands/inference.js +207 -0
  18. package/src/commands/kg.js +195 -0
  19. package/src/commands/llm.js +209 -0
  20. package/src/commands/memory.js +203 -0
  21. package/src/commands/orchestrate.js +406 -0
  22. package/src/commands/pipeline.js +199 -0
  23. package/src/commands/planmode.js +426 -0
  24. package/src/commands/plugin.js +209 -0
  25. package/src/commands/services.js +207 -0
  26. package/src/commands/setup.js +205 -0
  27. package/src/commands/skill.js +207 -0
  28. package/src/commands/start.js +209 -0
  29. package/src/commands/stream.js +213 -0
  30. package/src/commands/ui.js +225 -0
  31. package/src/commands/workflow.js +209 -0
  32. package/src/index.js +112 -0
  33. package/src/lib/a2a-protocol.js +332 -0
  34. package/src/lib/agent-coordinator.js +334 -0
  35. package/src/lib/agent-economy.js +334 -0
  36. package/src/lib/agent-router.js +333 -0
  37. package/src/lib/autonomous-agent.js +332 -0
  38. package/src/lib/chat-core.js +335 -0
  39. package/src/lib/cli-anything-bridge.js +341 -0
  40. package/src/lib/cli-context-engineering.js +351 -0
  41. package/src/lib/compliance-manager.js +334 -0
  42. package/src/lib/cowork-adapter.js +336 -0
  43. package/src/lib/cowork-evomap-adapter.js +341 -0
  44. package/src/lib/cowork-mcp-tools.js +341 -0
  45. package/src/lib/cowork-observe-html.js +341 -0
  46. package/src/lib/cowork-observe.js +341 -0
  47. package/src/lib/cowork-task-templates.js +342 -1
  48. package/src/lib/cowork-template-marketplace.js +340 -0
  49. package/src/lib/cross-chain.js +339 -0
  50. package/src/lib/crypto-manager.js +334 -0
  51. package/src/lib/dao-governance.js +339 -0
  52. package/src/lib/downloader.js +334 -0
  53. package/src/lib/evolution-system.js +334 -0
  54. package/src/lib/evomap-client.js +342 -0
  55. package/src/lib/evomap-federation.js +338 -0
  56. package/src/lib/evomap-manager.js +330 -0
  57. package/src/lib/execution-backend.js +330 -0
  58. package/src/lib/hashline.js +338 -0
  59. package/src/lib/hierarchical-memory.js +334 -0
  60. package/src/lib/inference-network.js +341 -0
  61. package/src/lib/interaction-adapter.js +330 -0
  62. package/src/lib/interactive-planner.js +354 -0
  63. package/src/lib/knowledge-graph.js +331 -0
  64. package/src/lib/pipeline-orchestrator.js +332 -0
  65. package/src/lib/plan-mode.js +336 -0
  66. package/src/lib/plugin-autodiscovery.js +334 -0
  67. package/src/lib/process-manager.js +336 -0
  68. package/src/lib/provider-options.js +346 -0
  69. package/src/lib/provider-stream.js +348 -0
  70. package/src/lib/service-manager.js +337 -0
  71. package/src/lib/session-core-singletons.js +341 -0
  72. package/src/lib/skill-mcp.js +336 -0
  73. package/src/lib/stix-parser.js +346 -0
  74. package/src/lib/sub-agent-context.js +343 -0
  75. package/src/lib/sub-agent-profiles.js +335 -0
  76. package/src/lib/sub-agent-registry.js +336 -0
  77. package/src/lib/todo-manager.js +336 -0
  78. package/src/lib/web-ui-server.js +348 -0
  79. package/src/lib/workflow-expr.js +346 -0
  80. package/src/lib/ws-chat-handler.js +337 -0
@@ -133,3 +133,345 @@ export class EvoMapClient {
133
133
  }
134
134
  }
135
135
  }
136
+
137
+ // =====================================================================
138
+ // evomap-client V2 governance overlay (iter27)
139
+ // =====================================================================
140
+ export const EVCLIGOV_PROFILE_MATURITY_V2 = Object.freeze({
141
+ PENDING: "pending",
142
+ ACTIVE: "active",
143
+ STALE: "stale",
144
+ ARCHIVED: "archived",
145
+ });
146
+ export const EVCLIGOV_RPC_LIFECYCLE_V2 = Object.freeze({
147
+ QUEUED: "queued",
148
+ CALLING: "calling",
149
+ RETURNED: "returned",
150
+ FAILED: "failed",
151
+ CANCELLED: "cancelled",
152
+ });
153
+ const _evcligovPTrans = new Map([
154
+ [
155
+ EVCLIGOV_PROFILE_MATURITY_V2.PENDING,
156
+ new Set([
157
+ EVCLIGOV_PROFILE_MATURITY_V2.ACTIVE,
158
+ EVCLIGOV_PROFILE_MATURITY_V2.ARCHIVED,
159
+ ]),
160
+ ],
161
+ [
162
+ EVCLIGOV_PROFILE_MATURITY_V2.ACTIVE,
163
+ new Set([
164
+ EVCLIGOV_PROFILE_MATURITY_V2.STALE,
165
+ EVCLIGOV_PROFILE_MATURITY_V2.ARCHIVED,
166
+ ]),
167
+ ],
168
+ [
169
+ EVCLIGOV_PROFILE_MATURITY_V2.STALE,
170
+ new Set([
171
+ EVCLIGOV_PROFILE_MATURITY_V2.ACTIVE,
172
+ EVCLIGOV_PROFILE_MATURITY_V2.ARCHIVED,
173
+ ]),
174
+ ],
175
+ [EVCLIGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
176
+ ]);
177
+ const _evcligovPTerminal = new Set([EVCLIGOV_PROFILE_MATURITY_V2.ARCHIVED]);
178
+ const _evcligovJTrans = new Map([
179
+ [
180
+ EVCLIGOV_RPC_LIFECYCLE_V2.QUEUED,
181
+ new Set([
182
+ EVCLIGOV_RPC_LIFECYCLE_V2.CALLING,
183
+ EVCLIGOV_RPC_LIFECYCLE_V2.CANCELLED,
184
+ ]),
185
+ ],
186
+ [
187
+ EVCLIGOV_RPC_LIFECYCLE_V2.CALLING,
188
+ new Set([
189
+ EVCLIGOV_RPC_LIFECYCLE_V2.RETURNED,
190
+ EVCLIGOV_RPC_LIFECYCLE_V2.FAILED,
191
+ EVCLIGOV_RPC_LIFECYCLE_V2.CANCELLED,
192
+ ]),
193
+ ],
194
+ [EVCLIGOV_RPC_LIFECYCLE_V2.RETURNED, new Set()],
195
+ [EVCLIGOV_RPC_LIFECYCLE_V2.FAILED, new Set()],
196
+ [EVCLIGOV_RPC_LIFECYCLE_V2.CANCELLED, new Set()],
197
+ ]);
198
+ const _evcligovPsV2 = new Map();
199
+ const _evcligovJsV2 = new Map();
200
+ let _evcligovMaxActive = 6,
201
+ _evcligovMaxPending = 15,
202
+ _evcligovIdleMs = 30 * 24 * 60 * 60 * 1000,
203
+ _evcligovStuckMs = 60 * 1000;
204
+ function _evcligovPos(n, label) {
205
+ const v = Math.floor(Number(n));
206
+ if (!Number.isFinite(v) || v <= 0)
207
+ throw new Error(`${label} must be positive integer`);
208
+ return v;
209
+ }
210
+ function _evcligovCheckP(from, to) {
211
+ const a = _evcligovPTrans.get(from);
212
+ if (!a || !a.has(to))
213
+ throw new Error(`invalid evcligov profile transition ${from} → ${to}`);
214
+ }
215
+ function _evcligovCheckJ(from, to) {
216
+ const a = _evcligovJTrans.get(from);
217
+ if (!a || !a.has(to))
218
+ throw new Error(`invalid evcligov rpc transition ${from} → ${to}`);
219
+ }
220
+ function _evcligovCountActive(owner) {
221
+ let c = 0;
222
+ for (const p of _evcligovPsV2.values())
223
+ if (p.owner === owner && p.status === EVCLIGOV_PROFILE_MATURITY_V2.ACTIVE)
224
+ c++;
225
+ return c;
226
+ }
227
+ function _evcligovCountPending(profileId) {
228
+ let c = 0;
229
+ for (const j of _evcligovJsV2.values())
230
+ if (
231
+ j.profileId === profileId &&
232
+ (j.status === EVCLIGOV_RPC_LIFECYCLE_V2.QUEUED ||
233
+ j.status === EVCLIGOV_RPC_LIFECYCLE_V2.CALLING)
234
+ )
235
+ c++;
236
+ return c;
237
+ }
238
+ export function setMaxActiveEvcligovProfilesPerOwnerV2(n) {
239
+ _evcligovMaxActive = _evcligovPos(n, "maxActiveEvcligovProfilesPerOwner");
240
+ }
241
+ export function getMaxActiveEvcligovProfilesPerOwnerV2() {
242
+ return _evcligovMaxActive;
243
+ }
244
+ export function setMaxPendingEvcligovRpcsPerProfileV2(n) {
245
+ _evcligovMaxPending = _evcligovPos(n, "maxPendingEvcligovRpcsPerProfile");
246
+ }
247
+ export function getMaxPendingEvcligovRpcsPerProfileV2() {
248
+ return _evcligovMaxPending;
249
+ }
250
+ export function setEvcligovProfileIdleMsV2(n) {
251
+ _evcligovIdleMs = _evcligovPos(n, "evcligovProfileIdleMs");
252
+ }
253
+ export function getEvcligovProfileIdleMsV2() {
254
+ return _evcligovIdleMs;
255
+ }
256
+ export function setEvcligovRpcStuckMsV2(n) {
257
+ _evcligovStuckMs = _evcligovPos(n, "evcligovRpcStuckMs");
258
+ }
259
+ export function getEvcligovRpcStuckMsV2() {
260
+ return _evcligovStuckMs;
261
+ }
262
+ export function _resetStateEvomapClientGovV2() {
263
+ _evcligovPsV2.clear();
264
+ _evcligovJsV2.clear();
265
+ _evcligovMaxActive = 6;
266
+ _evcligovMaxPending = 15;
267
+ _evcligovIdleMs = 30 * 24 * 60 * 60 * 1000;
268
+ _evcligovStuckMs = 60 * 1000;
269
+ }
270
+ export function registerEvcligovProfileV2({
271
+ id,
272
+ owner,
273
+ endpoint,
274
+ metadata,
275
+ } = {}) {
276
+ if (!id || !owner) throw new Error("id and owner required");
277
+ if (_evcligovPsV2.has(id))
278
+ throw new Error(`evcligov profile ${id} already exists`);
279
+ const now = Date.now();
280
+ const p = {
281
+ id,
282
+ owner,
283
+ endpoint: endpoint || "primary",
284
+ status: EVCLIGOV_PROFILE_MATURITY_V2.PENDING,
285
+ createdAt: now,
286
+ updatedAt: now,
287
+ lastTouchedAt: now,
288
+ activatedAt: null,
289
+ archivedAt: null,
290
+ metadata: { ...(metadata || {}) },
291
+ };
292
+ _evcligovPsV2.set(id, p);
293
+ return { ...p, metadata: { ...p.metadata } };
294
+ }
295
+ export function activateEvcligovProfileV2(id) {
296
+ const p = _evcligovPsV2.get(id);
297
+ if (!p) throw new Error(`evcligov profile ${id} not found`);
298
+ const isInitial = p.status === EVCLIGOV_PROFILE_MATURITY_V2.PENDING;
299
+ _evcligovCheckP(p.status, EVCLIGOV_PROFILE_MATURITY_V2.ACTIVE);
300
+ if (isInitial && _evcligovCountActive(p.owner) >= _evcligovMaxActive)
301
+ throw new Error(
302
+ `max active evcligov profiles for owner ${p.owner} reached`,
303
+ );
304
+ const now = Date.now();
305
+ p.status = EVCLIGOV_PROFILE_MATURITY_V2.ACTIVE;
306
+ p.updatedAt = now;
307
+ p.lastTouchedAt = now;
308
+ if (!p.activatedAt) p.activatedAt = now;
309
+ return { ...p, metadata: { ...p.metadata } };
310
+ }
311
+ export function staleEvcligovProfileV2(id) {
312
+ const p = _evcligovPsV2.get(id);
313
+ if (!p) throw new Error(`evcligov profile ${id} not found`);
314
+ _evcligovCheckP(p.status, EVCLIGOV_PROFILE_MATURITY_V2.STALE);
315
+ p.status = EVCLIGOV_PROFILE_MATURITY_V2.STALE;
316
+ p.updatedAt = Date.now();
317
+ return { ...p, metadata: { ...p.metadata } };
318
+ }
319
+ export function archiveEvcligovProfileV2(id) {
320
+ const p = _evcligovPsV2.get(id);
321
+ if (!p) throw new Error(`evcligov profile ${id} not found`);
322
+ _evcligovCheckP(p.status, EVCLIGOV_PROFILE_MATURITY_V2.ARCHIVED);
323
+ const now = Date.now();
324
+ p.status = EVCLIGOV_PROFILE_MATURITY_V2.ARCHIVED;
325
+ p.updatedAt = now;
326
+ if (!p.archivedAt) p.archivedAt = now;
327
+ return { ...p, metadata: { ...p.metadata } };
328
+ }
329
+ export function touchEvcligovProfileV2(id) {
330
+ const p = _evcligovPsV2.get(id);
331
+ if (!p) throw new Error(`evcligov profile ${id} not found`);
332
+ if (_evcligovPTerminal.has(p.status))
333
+ throw new Error(`cannot touch terminal evcligov profile ${id}`);
334
+ const now = Date.now();
335
+ p.lastTouchedAt = now;
336
+ p.updatedAt = now;
337
+ return { ...p, metadata: { ...p.metadata } };
338
+ }
339
+ export function getEvcligovProfileV2(id) {
340
+ const p = _evcligovPsV2.get(id);
341
+ if (!p) return null;
342
+ return { ...p, metadata: { ...p.metadata } };
343
+ }
344
+ export function listEvcligovProfilesV2() {
345
+ return [..._evcligovPsV2.values()].map((p) => ({
346
+ ...p,
347
+ metadata: { ...p.metadata },
348
+ }));
349
+ }
350
+ export function createEvcligovRpcV2({ id, profileId, method, metadata } = {}) {
351
+ if (!id || !profileId) throw new Error("id and profileId required");
352
+ if (_evcligovJsV2.has(id))
353
+ throw new Error(`evcligov rpc ${id} already exists`);
354
+ if (!_evcligovPsV2.has(profileId))
355
+ throw new Error(`evcligov profile ${profileId} not found`);
356
+ if (_evcligovCountPending(profileId) >= _evcligovMaxPending)
357
+ throw new Error(
358
+ `max pending evcligov rpcs for profile ${profileId} reached`,
359
+ );
360
+ const now = Date.now();
361
+ const j = {
362
+ id,
363
+ profileId,
364
+ method: method || "",
365
+ status: EVCLIGOV_RPC_LIFECYCLE_V2.QUEUED,
366
+ createdAt: now,
367
+ updatedAt: now,
368
+ startedAt: null,
369
+ settledAt: null,
370
+ metadata: { ...(metadata || {}) },
371
+ };
372
+ _evcligovJsV2.set(id, j);
373
+ return { ...j, metadata: { ...j.metadata } };
374
+ }
375
+ export function callingEvcligovRpcV2(id) {
376
+ const j = _evcligovJsV2.get(id);
377
+ if (!j) throw new Error(`evcligov rpc ${id} not found`);
378
+ _evcligovCheckJ(j.status, EVCLIGOV_RPC_LIFECYCLE_V2.CALLING);
379
+ const now = Date.now();
380
+ j.status = EVCLIGOV_RPC_LIFECYCLE_V2.CALLING;
381
+ j.updatedAt = now;
382
+ if (!j.startedAt) j.startedAt = now;
383
+ return { ...j, metadata: { ...j.metadata } };
384
+ }
385
+ export function completeRpcEvcligovV2(id) {
386
+ const j = _evcligovJsV2.get(id);
387
+ if (!j) throw new Error(`evcligov rpc ${id} not found`);
388
+ _evcligovCheckJ(j.status, EVCLIGOV_RPC_LIFECYCLE_V2.RETURNED);
389
+ const now = Date.now();
390
+ j.status = EVCLIGOV_RPC_LIFECYCLE_V2.RETURNED;
391
+ j.updatedAt = now;
392
+ if (!j.settledAt) j.settledAt = now;
393
+ return { ...j, metadata: { ...j.metadata } };
394
+ }
395
+ export function failEvcligovRpcV2(id, reason) {
396
+ const j = _evcligovJsV2.get(id);
397
+ if (!j) throw new Error(`evcligov rpc ${id} not found`);
398
+ _evcligovCheckJ(j.status, EVCLIGOV_RPC_LIFECYCLE_V2.FAILED);
399
+ const now = Date.now();
400
+ j.status = EVCLIGOV_RPC_LIFECYCLE_V2.FAILED;
401
+ j.updatedAt = now;
402
+ if (!j.settledAt) j.settledAt = now;
403
+ if (reason) j.metadata.failReason = String(reason);
404
+ return { ...j, metadata: { ...j.metadata } };
405
+ }
406
+ export function cancelEvcligovRpcV2(id, reason) {
407
+ const j = _evcligovJsV2.get(id);
408
+ if (!j) throw new Error(`evcligov rpc ${id} not found`);
409
+ _evcligovCheckJ(j.status, EVCLIGOV_RPC_LIFECYCLE_V2.CANCELLED);
410
+ const now = Date.now();
411
+ j.status = EVCLIGOV_RPC_LIFECYCLE_V2.CANCELLED;
412
+ j.updatedAt = now;
413
+ if (!j.settledAt) j.settledAt = now;
414
+ if (reason) j.metadata.cancelReason = String(reason);
415
+ return { ...j, metadata: { ...j.metadata } };
416
+ }
417
+ export function getEvcligovRpcV2(id) {
418
+ const j = _evcligovJsV2.get(id);
419
+ if (!j) return null;
420
+ return { ...j, metadata: { ...j.metadata } };
421
+ }
422
+ export function listEvcligovRpcsV2() {
423
+ return [..._evcligovJsV2.values()].map((j) => ({
424
+ ...j,
425
+ metadata: { ...j.metadata },
426
+ }));
427
+ }
428
+ export function autoStaleIdleEvcligovProfilesV2({ now } = {}) {
429
+ const t = now ?? Date.now();
430
+ const flipped = [];
431
+ for (const p of _evcligovPsV2.values())
432
+ if (
433
+ p.status === EVCLIGOV_PROFILE_MATURITY_V2.ACTIVE &&
434
+ t - p.lastTouchedAt >= _evcligovIdleMs
435
+ ) {
436
+ p.status = EVCLIGOV_PROFILE_MATURITY_V2.STALE;
437
+ p.updatedAt = t;
438
+ flipped.push(p.id);
439
+ }
440
+ return { flipped, count: flipped.length };
441
+ }
442
+ export function autoFailStuckEvcligovRpcsV2({ now } = {}) {
443
+ const t = now ?? Date.now();
444
+ const flipped = [];
445
+ for (const j of _evcligovJsV2.values())
446
+ if (
447
+ j.status === EVCLIGOV_RPC_LIFECYCLE_V2.CALLING &&
448
+ j.startedAt != null &&
449
+ t - j.startedAt >= _evcligovStuckMs
450
+ ) {
451
+ j.status = EVCLIGOV_RPC_LIFECYCLE_V2.FAILED;
452
+ j.updatedAt = t;
453
+ if (!j.settledAt) j.settledAt = t;
454
+ j.metadata.failReason = "auto-fail-stuck";
455
+ flipped.push(j.id);
456
+ }
457
+ return { flipped, count: flipped.length };
458
+ }
459
+ export function getEvomapClientGovStatsV2() {
460
+ const profilesByStatus = {};
461
+ for (const v of Object.values(EVCLIGOV_PROFILE_MATURITY_V2))
462
+ profilesByStatus[v] = 0;
463
+ for (const p of _evcligovPsV2.values()) profilesByStatus[p.status]++;
464
+ const rpcsByStatus = {};
465
+ for (const v of Object.values(EVCLIGOV_RPC_LIFECYCLE_V2)) rpcsByStatus[v] = 0;
466
+ for (const j of _evcligovJsV2.values()) rpcsByStatus[j.status]++;
467
+ return {
468
+ totalEvcligovProfilesV2: _evcligovPsV2.size,
469
+ totalEvcligovRpcsV2: _evcligovJsV2.size,
470
+ maxActiveEvcligovProfilesPerOwner: _evcligovMaxActive,
471
+ maxPendingEvcligovRpcsPerProfile: _evcligovMaxPending,
472
+ evcligovProfileIdleMs: _evcligovIdleMs,
473
+ evcligovRpcStuckMs: _evcligovStuckMs,
474
+ profilesByStatus,
475
+ rpcsByStatus,
476
+ };
477
+ }
@@ -415,3 +415,341 @@ export function getFederationStatsV2() {
415
415
  byMutationType,
416
416
  };
417
417
  }
418
+
419
+ // =====================================================================
420
+ // evomap-federation V2 governance overlay (iter25)
421
+ // =====================================================================
422
+ export const EVFEDGOV_PROFILE_MATURITY_V2 = Object.freeze({
423
+ PENDING: "pending",
424
+ ACTIVE: "active",
425
+ STALE: "stale",
426
+ ARCHIVED: "archived",
427
+ });
428
+ export const EVFEDGOV_SYNC_LIFECYCLE_V2 = Object.freeze({
429
+ QUEUED: "queued",
430
+ SYNCING: "syncing",
431
+ SYNCED: "synced",
432
+ FAILED: "failed",
433
+ CANCELLED: "cancelled",
434
+ });
435
+ const _evfedgovPTrans = new Map([
436
+ [
437
+ EVFEDGOV_PROFILE_MATURITY_V2.PENDING,
438
+ new Set([
439
+ EVFEDGOV_PROFILE_MATURITY_V2.ACTIVE,
440
+ EVFEDGOV_PROFILE_MATURITY_V2.ARCHIVED,
441
+ ]),
442
+ ],
443
+ [
444
+ EVFEDGOV_PROFILE_MATURITY_V2.ACTIVE,
445
+ new Set([
446
+ EVFEDGOV_PROFILE_MATURITY_V2.STALE,
447
+ EVFEDGOV_PROFILE_MATURITY_V2.ARCHIVED,
448
+ ]),
449
+ ],
450
+ [
451
+ EVFEDGOV_PROFILE_MATURITY_V2.STALE,
452
+ new Set([
453
+ EVFEDGOV_PROFILE_MATURITY_V2.ACTIVE,
454
+ EVFEDGOV_PROFILE_MATURITY_V2.ARCHIVED,
455
+ ]),
456
+ ],
457
+ [EVFEDGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
458
+ ]);
459
+ const _evfedgovPTerminal = new Set([EVFEDGOV_PROFILE_MATURITY_V2.ARCHIVED]);
460
+ const _evfedgovJTrans = new Map([
461
+ [
462
+ EVFEDGOV_SYNC_LIFECYCLE_V2.QUEUED,
463
+ new Set([
464
+ EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCING,
465
+ EVFEDGOV_SYNC_LIFECYCLE_V2.CANCELLED,
466
+ ]),
467
+ ],
468
+ [
469
+ EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCING,
470
+ new Set([
471
+ EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCED,
472
+ EVFEDGOV_SYNC_LIFECYCLE_V2.FAILED,
473
+ EVFEDGOV_SYNC_LIFECYCLE_V2.CANCELLED,
474
+ ]),
475
+ ],
476
+ [EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCED, new Set()],
477
+ [EVFEDGOV_SYNC_LIFECYCLE_V2.FAILED, new Set()],
478
+ [EVFEDGOV_SYNC_LIFECYCLE_V2.CANCELLED, new Set()],
479
+ ]);
480
+ const _evfedgovPsV2 = new Map();
481
+ const _evfedgovJsV2 = new Map();
482
+ let _evfedgovMaxActive = 6,
483
+ _evfedgovMaxPending = 15,
484
+ _evfedgovIdleMs = 30 * 24 * 60 * 60 * 1000,
485
+ _evfedgovStuckMs = 60 * 1000;
486
+ function _evfedgovPos(n, label) {
487
+ const v = Math.floor(Number(n));
488
+ if (!Number.isFinite(v) || v <= 0)
489
+ throw new Error(`${label} must be positive integer`);
490
+ return v;
491
+ }
492
+ function _evfedgovCheckP(from, to) {
493
+ const a = _evfedgovPTrans.get(from);
494
+ if (!a || !a.has(to))
495
+ throw new Error(`invalid evfedgov profile transition ${from} → ${to}`);
496
+ }
497
+ function _evfedgovCheckJ(from, to) {
498
+ const a = _evfedgovJTrans.get(from);
499
+ if (!a || !a.has(to))
500
+ throw new Error(`invalid evfedgov sync transition ${from} → ${to}`);
501
+ }
502
+ function _evfedgovCountActive(owner) {
503
+ let c = 0;
504
+ for (const p of _evfedgovPsV2.values())
505
+ if (p.owner === owner && p.status === EVFEDGOV_PROFILE_MATURITY_V2.ACTIVE)
506
+ c++;
507
+ return c;
508
+ }
509
+ function _evfedgovCountPending(profileId) {
510
+ let c = 0;
511
+ for (const j of _evfedgovJsV2.values())
512
+ if (
513
+ j.profileId === profileId &&
514
+ (j.status === EVFEDGOV_SYNC_LIFECYCLE_V2.QUEUED ||
515
+ j.status === EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCING)
516
+ )
517
+ c++;
518
+ return c;
519
+ }
520
+ export function setMaxActiveEvfedgovProfilesPerOwnerV2(n) {
521
+ _evfedgovMaxActive = _evfedgovPos(n, "maxActiveEvfedgovProfilesPerOwner");
522
+ }
523
+ export function getMaxActiveEvfedgovProfilesPerOwnerV2() {
524
+ return _evfedgovMaxActive;
525
+ }
526
+ export function setMaxPendingEvfedgovSyncsPerProfileV2(n) {
527
+ _evfedgovMaxPending = _evfedgovPos(n, "maxPendingEvfedgovSyncsPerProfile");
528
+ }
529
+ export function getMaxPendingEvfedgovSyncsPerProfileV2() {
530
+ return _evfedgovMaxPending;
531
+ }
532
+ export function setEvfedgovProfileIdleMsV2(n) {
533
+ _evfedgovIdleMs = _evfedgovPos(n, "evfedgovProfileIdleMs");
534
+ }
535
+ export function getEvfedgovProfileIdleMsV2() {
536
+ return _evfedgovIdleMs;
537
+ }
538
+ export function setEvfedgovSyncStuckMsV2(n) {
539
+ _evfedgovStuckMs = _evfedgovPos(n, "evfedgovSyncStuckMs");
540
+ }
541
+ export function getEvfedgovSyncStuckMsV2() {
542
+ return _evfedgovStuckMs;
543
+ }
544
+ export function _resetStateEvomapFederationGovV2() {
545
+ _evfedgovPsV2.clear();
546
+ _evfedgovJsV2.clear();
547
+ _evfedgovMaxActive = 6;
548
+ _evfedgovMaxPending = 15;
549
+ _evfedgovIdleMs = 30 * 24 * 60 * 60 * 1000;
550
+ _evfedgovStuckMs = 60 * 1000;
551
+ }
552
+ export function registerEvfedgovProfileV2({ id, owner, hub, metadata } = {}) {
553
+ if (!id || !owner) throw new Error("id and owner required");
554
+ if (_evfedgovPsV2.has(id))
555
+ throw new Error(`evfedgov profile ${id} already exists`);
556
+ const now = Date.now();
557
+ const p = {
558
+ id,
559
+ owner,
560
+ hub: hub || "primary",
561
+ status: EVFEDGOV_PROFILE_MATURITY_V2.PENDING,
562
+ createdAt: now,
563
+ updatedAt: now,
564
+ lastTouchedAt: now,
565
+ activatedAt: null,
566
+ archivedAt: null,
567
+ metadata: { ...(metadata || {}) },
568
+ };
569
+ _evfedgovPsV2.set(id, p);
570
+ return { ...p, metadata: { ...p.metadata } };
571
+ }
572
+ export function activateEvfedgovProfileV2(id) {
573
+ const p = _evfedgovPsV2.get(id);
574
+ if (!p) throw new Error(`evfedgov profile ${id} not found`);
575
+ const isInitial = p.status === EVFEDGOV_PROFILE_MATURITY_V2.PENDING;
576
+ _evfedgovCheckP(p.status, EVFEDGOV_PROFILE_MATURITY_V2.ACTIVE);
577
+ if (isInitial && _evfedgovCountActive(p.owner) >= _evfedgovMaxActive)
578
+ throw new Error(
579
+ `max active evfedgov profiles for owner ${p.owner} reached`,
580
+ );
581
+ const now = Date.now();
582
+ p.status = EVFEDGOV_PROFILE_MATURITY_V2.ACTIVE;
583
+ p.updatedAt = now;
584
+ p.lastTouchedAt = now;
585
+ if (!p.activatedAt) p.activatedAt = now;
586
+ return { ...p, metadata: { ...p.metadata } };
587
+ }
588
+ export function staleEvfedgovProfileV2(id) {
589
+ const p = _evfedgovPsV2.get(id);
590
+ if (!p) throw new Error(`evfedgov profile ${id} not found`);
591
+ _evfedgovCheckP(p.status, EVFEDGOV_PROFILE_MATURITY_V2.STALE);
592
+ p.status = EVFEDGOV_PROFILE_MATURITY_V2.STALE;
593
+ p.updatedAt = Date.now();
594
+ return { ...p, metadata: { ...p.metadata } };
595
+ }
596
+ export function archiveEvfedgovProfileV2(id) {
597
+ const p = _evfedgovPsV2.get(id);
598
+ if (!p) throw new Error(`evfedgov profile ${id} not found`);
599
+ _evfedgovCheckP(p.status, EVFEDGOV_PROFILE_MATURITY_V2.ARCHIVED);
600
+ const now = Date.now();
601
+ p.status = EVFEDGOV_PROFILE_MATURITY_V2.ARCHIVED;
602
+ p.updatedAt = now;
603
+ if (!p.archivedAt) p.archivedAt = now;
604
+ return { ...p, metadata: { ...p.metadata } };
605
+ }
606
+ export function touchEvfedgovProfileV2(id) {
607
+ const p = _evfedgovPsV2.get(id);
608
+ if (!p) throw new Error(`evfedgov profile ${id} not found`);
609
+ if (_evfedgovPTerminal.has(p.status))
610
+ throw new Error(`cannot touch terminal evfedgov profile ${id}`);
611
+ const now = Date.now();
612
+ p.lastTouchedAt = now;
613
+ p.updatedAt = now;
614
+ return { ...p, metadata: { ...p.metadata } };
615
+ }
616
+ export function getEvfedgovProfileV2(id) {
617
+ const p = _evfedgovPsV2.get(id);
618
+ if (!p) return null;
619
+ return { ...p, metadata: { ...p.metadata } };
620
+ }
621
+ export function listEvfedgovProfilesV2() {
622
+ return [..._evfedgovPsV2.values()].map((p) => ({
623
+ ...p,
624
+ metadata: { ...p.metadata },
625
+ }));
626
+ }
627
+ export function createEvfedgovSyncV2({ id, profileId, geneId, metadata } = {}) {
628
+ if (!id || !profileId) throw new Error("id and profileId required");
629
+ if (_evfedgovJsV2.has(id))
630
+ throw new Error(`evfedgov sync ${id} already exists`);
631
+ if (!_evfedgovPsV2.has(profileId))
632
+ throw new Error(`evfedgov profile ${profileId} not found`);
633
+ if (_evfedgovCountPending(profileId) >= _evfedgovMaxPending)
634
+ throw new Error(
635
+ `max pending evfedgov syncs for profile ${profileId} reached`,
636
+ );
637
+ const now = Date.now();
638
+ const j = {
639
+ id,
640
+ profileId,
641
+ geneId: geneId || "",
642
+ status: EVFEDGOV_SYNC_LIFECYCLE_V2.QUEUED,
643
+ createdAt: now,
644
+ updatedAt: now,
645
+ startedAt: null,
646
+ settledAt: null,
647
+ metadata: { ...(metadata || {}) },
648
+ };
649
+ _evfedgovJsV2.set(id, j);
650
+ return { ...j, metadata: { ...j.metadata } };
651
+ }
652
+ export function syncingEvfedgovSyncV2(id) {
653
+ const j = _evfedgovJsV2.get(id);
654
+ if (!j) throw new Error(`evfedgov sync ${id} not found`);
655
+ _evfedgovCheckJ(j.status, EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCING);
656
+ const now = Date.now();
657
+ j.status = EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCING;
658
+ j.updatedAt = now;
659
+ if (!j.startedAt) j.startedAt = now;
660
+ return { ...j, metadata: { ...j.metadata } };
661
+ }
662
+ export function completeSyncEvfedgovV2(id) {
663
+ const j = _evfedgovJsV2.get(id);
664
+ if (!j) throw new Error(`evfedgov sync ${id} not found`);
665
+ _evfedgovCheckJ(j.status, EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCED);
666
+ const now = Date.now();
667
+ j.status = EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCED;
668
+ j.updatedAt = now;
669
+ if (!j.settledAt) j.settledAt = now;
670
+ return { ...j, metadata: { ...j.metadata } };
671
+ }
672
+ export function failEvfedgovSyncV2(id, reason) {
673
+ const j = _evfedgovJsV2.get(id);
674
+ if (!j) throw new Error(`evfedgov sync ${id} not found`);
675
+ _evfedgovCheckJ(j.status, EVFEDGOV_SYNC_LIFECYCLE_V2.FAILED);
676
+ const now = Date.now();
677
+ j.status = EVFEDGOV_SYNC_LIFECYCLE_V2.FAILED;
678
+ j.updatedAt = now;
679
+ if (!j.settledAt) j.settledAt = now;
680
+ if (reason) j.metadata.failReason = String(reason);
681
+ return { ...j, metadata: { ...j.metadata } };
682
+ }
683
+ export function cancelEvfedgovSyncV2(id, reason) {
684
+ const j = _evfedgovJsV2.get(id);
685
+ if (!j) throw new Error(`evfedgov sync ${id} not found`);
686
+ _evfedgovCheckJ(j.status, EVFEDGOV_SYNC_LIFECYCLE_V2.CANCELLED);
687
+ const now = Date.now();
688
+ j.status = EVFEDGOV_SYNC_LIFECYCLE_V2.CANCELLED;
689
+ j.updatedAt = now;
690
+ if (!j.settledAt) j.settledAt = now;
691
+ if (reason) j.metadata.cancelReason = String(reason);
692
+ return { ...j, metadata: { ...j.metadata } };
693
+ }
694
+ export function getEvfedgovSyncV2(id) {
695
+ const j = _evfedgovJsV2.get(id);
696
+ if (!j) return null;
697
+ return { ...j, metadata: { ...j.metadata } };
698
+ }
699
+ export function listEvfedgovSyncsV2() {
700
+ return [..._evfedgovJsV2.values()].map((j) => ({
701
+ ...j,
702
+ metadata: { ...j.metadata },
703
+ }));
704
+ }
705
+ export function autoStaleIdleEvfedgovProfilesV2({ now } = {}) {
706
+ const t = now ?? Date.now();
707
+ const flipped = [];
708
+ for (const p of _evfedgovPsV2.values())
709
+ if (
710
+ p.status === EVFEDGOV_PROFILE_MATURITY_V2.ACTIVE &&
711
+ t - p.lastTouchedAt >= _evfedgovIdleMs
712
+ ) {
713
+ p.status = EVFEDGOV_PROFILE_MATURITY_V2.STALE;
714
+ p.updatedAt = t;
715
+ flipped.push(p.id);
716
+ }
717
+ return { flipped, count: flipped.length };
718
+ }
719
+ export function autoFailStuckEvfedgovSyncsV2({ now } = {}) {
720
+ const t = now ?? Date.now();
721
+ const flipped = [];
722
+ for (const j of _evfedgovJsV2.values())
723
+ if (
724
+ j.status === EVFEDGOV_SYNC_LIFECYCLE_V2.SYNCING &&
725
+ j.startedAt != null &&
726
+ t - j.startedAt >= _evfedgovStuckMs
727
+ ) {
728
+ j.status = EVFEDGOV_SYNC_LIFECYCLE_V2.FAILED;
729
+ j.updatedAt = t;
730
+ if (!j.settledAt) j.settledAt = t;
731
+ j.metadata.failReason = "auto-fail-stuck";
732
+ flipped.push(j.id);
733
+ }
734
+ return { flipped, count: flipped.length };
735
+ }
736
+ export function getEvomapFederationGovStatsV2() {
737
+ const profilesByStatus = {};
738
+ for (const v of Object.values(EVFEDGOV_PROFILE_MATURITY_V2))
739
+ profilesByStatus[v] = 0;
740
+ for (const p of _evfedgovPsV2.values()) profilesByStatus[p.status]++;
741
+ const syncsByStatus = {};
742
+ for (const v of Object.values(EVFEDGOV_SYNC_LIFECYCLE_V2))
743
+ syncsByStatus[v] = 0;
744
+ for (const j of _evfedgovJsV2.values()) syncsByStatus[j.status]++;
745
+ return {
746
+ totalEvfedgovProfilesV2: _evfedgovPsV2.size,
747
+ totalEvfedgovSyncsV2: _evfedgovJsV2.size,
748
+ maxActiveEvfedgovProfilesPerOwner: _evfedgovMaxActive,
749
+ maxPendingEvfedgovSyncsPerProfile: _evfedgovMaxPending,
750
+ evfedgovProfileIdleMs: _evfedgovIdleMs,
751
+ evfedgovSyncStuckMs: _evfedgovStuckMs,
752
+ profilesByStatus,
753
+ syncsByStatus,
754
+ };
755
+ }