chainlesschain 0.143.0 → 0.152.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 (227) hide show
  1. package/package.json +1 -1
  2. package/src/commands/a2a.js +196 -28
  3. package/src/commands/activitypub.js +364 -27
  4. package/src/commands/agent-network.js +217 -0
  5. package/src/commands/agent.js +587 -103
  6. package/src/commands/audit.js +206 -0
  7. package/src/commands/automation.js +201 -0
  8. package/src/commands/bi.js +355 -27
  9. package/src/commands/bm25.js +111 -27
  10. package/src/commands/browse.js +403 -29
  11. package/src/commands/ccron.js +128 -28
  12. package/src/commands/chat.js +207 -0
  13. package/src/commands/codegen.js +207 -0
  14. package/src/commands/collab.js +211 -0
  15. package/src/commands/compliance.js +824 -34
  16. package/src/commands/compt.js +127 -29
  17. package/src/commands/consol.js +8 -2
  18. package/src/commands/cowork.js +783 -34
  19. package/src/commands/crosschain.js +182 -28
  20. package/src/commands/dao.js +182 -28
  21. package/src/commands/dbevo.js +227 -0
  22. package/src/commands/dev.js +207 -0
  23. package/src/commands/did-v2.js +217 -0
  24. package/src/commands/did.js +221 -0
  25. package/src/commands/dlp.js +385 -27
  26. package/src/commands/economy.js +205 -50
  27. package/src/commands/evolution.js +203 -50
  28. package/src/commands/evomap.js +387 -27
  29. package/src/commands/export.js +213 -0
  30. package/src/commands/federation.js +209 -0
  31. package/src/commands/fflag.js +74 -22
  32. package/src/commands/fusion.js +205 -0
  33. package/src/commands/git.js +177 -37
  34. package/src/commands/governance.js +209 -0
  35. package/src/commands/hardening.js +209 -0
  36. package/src/commands/hmemory.js +204 -50
  37. package/src/commands/hook.js +209 -0
  38. package/src/commands/import.js +209 -0
  39. package/src/commands/incentive.js +209 -0
  40. package/src/commands/inference.js +170 -34
  41. package/src/commands/infra.js +203 -0
  42. package/src/commands/instinct.js +209 -0
  43. package/src/commands/ipfs.js +207 -0
  44. package/src/commands/itbudget.js +149 -33
  45. package/src/commands/kg.js +206 -0
  46. package/src/commands/llm.js +217 -0
  47. package/src/commands/lowcode.js +195 -38
  48. package/src/commands/marketplace.js +206 -0
  49. package/src/commands/matrix.js +386 -27
  50. package/src/commands/mcp.js +217 -0
  51. package/src/commands/mcpscaf.js +145 -33
  52. package/src/commands/meminj.js +145 -33
  53. package/src/commands/memory.js +209 -0
  54. package/src/commands/multimodal.js +203 -0
  55. package/src/commands/nlprog.js +225 -0
  56. package/src/commands/nostr.js +387 -27
  57. package/src/commands/note.js +205 -0
  58. package/src/commands/ops.js +219 -0
  59. package/src/commands/orchestrate.js +217 -0
  60. package/src/commands/orchgov.js +144 -33
  61. package/src/commands/org.js +209 -0
  62. package/src/commands/p2p.js +209 -0
  63. package/src/commands/pdfp.js +109 -27
  64. package/src/commands/perception.js +209 -0
  65. package/src/commands/perf.js +169 -32
  66. package/src/commands/perm.js +144 -33
  67. package/src/commands/permmem.js +203 -0
  68. package/src/commands/pipeline.js +207 -52
  69. package/src/commands/planmode.js +141 -32
  70. package/src/commands/plugin-ecosystem.js +209 -0
  71. package/src/commands/pqc.js +213 -0
  72. package/src/commands/privacy.js +203 -0
  73. package/src/commands/promcomp.js +111 -27
  74. package/src/commands/quantization.js +207 -0
  75. package/src/commands/rcache.js +205 -0
  76. package/src/commands/recommend.js +410 -34
  77. package/src/commands/reputation.js +208 -0
  78. package/src/commands/runtime.js +205 -0
  79. package/src/commands/sandbox.js +206 -0
  80. package/src/commands/scim.js +209 -0
  81. package/src/commands/seshhook.js +145 -33
  82. package/src/commands/seshsearch.js +141 -33
  83. package/src/commands/seshtail.js +144 -33
  84. package/src/commands/seshu.js +152 -33
  85. package/src/commands/session.js +209 -0
  86. package/src/commands/sganal.js +123 -29
  87. package/src/commands/siem.js +201 -34
  88. package/src/commands/skill.js +207 -0
  89. package/src/commands/sla.js +212 -0
  90. package/src/commands/slotfill.js +146 -33
  91. package/src/commands/social.js +358 -32
  92. package/src/commands/sso.js +209 -0
  93. package/src/commands/stress.js +206 -0
  94. package/src/commands/svccont.js +145 -33
  95. package/src/commands/sync.js +209 -0
  96. package/src/commands/tech.js +209 -0
  97. package/src/commands/tenant.js +217 -0
  98. package/src/commands/terraform.js +206 -0
  99. package/src/commands/tms.js +171 -33
  100. package/src/commands/tokens.js +209 -0
  101. package/src/commands/topiccls.js +146 -33
  102. package/src/commands/trust.js +217 -0
  103. package/src/commands/uprof.js +141 -32
  104. package/src/commands/vcheck.js +122 -28
  105. package/src/commands/wallet.js +209 -0
  106. package/src/commands/webfetch.js +141 -32
  107. package/src/commands/workflow.js +203 -0
  108. package/src/commands/zkp.js +184 -28
  109. package/src/index.js +180 -0
  110. package/src/lib/a2a-protocol.js +319 -51
  111. package/src/lib/activitypub-bridge.js +622 -50
  112. package/src/lib/agent-economy.js +304 -51
  113. package/src/lib/agent-network.js +341 -0
  114. package/src/lib/aiops.js +346 -0
  115. package/src/lib/app-builder.js +279 -46
  116. package/src/lib/audit-logger.js +321 -0
  117. package/src/lib/automation-engine.js +335 -0
  118. package/src/lib/autonomous-agent.js +284 -48
  119. package/src/lib/autonomous-developer.js +332 -0
  120. package/src/lib/bi-engine.js +616 -49
  121. package/src/lib/bm25-search.js +301 -49
  122. package/src/lib/browser-automation.js +630 -49
  123. package/src/lib/chat-core.js +336 -0
  124. package/src/lib/claude-code-bridge.js +341 -0
  125. package/src/lib/code-agent.js +339 -0
  126. package/src/lib/collaboration-governance.js +334 -0
  127. package/src/lib/community-governance.js +346 -0
  128. package/src/lib/compliance-framework-reporter.js +305 -51
  129. package/src/lib/compliance-manager.js +330 -0
  130. package/src/lib/compression-telemetry.js +301 -49
  131. package/src/lib/content-recommendation.js +351 -0
  132. package/src/lib/content-recommender.js +317 -52
  133. package/src/lib/cowork-cron.js +298 -49
  134. package/src/lib/cowork-learning.js +333 -0
  135. package/src/lib/cowork-share.js +338 -0
  136. package/src/lib/cowork-task-runner.js +308 -51
  137. package/src/lib/cowork-workflow.js +327 -0
  138. package/src/lib/cross-chain.js +311 -51
  139. package/src/lib/dao-governance.js +280 -46
  140. package/src/lib/dbevo.js +351 -0
  141. package/src/lib/decentral-infra.js +330 -0
  142. package/src/lib/did-manager.js +341 -0
  143. package/src/lib/did-v2-manager.js +341 -0
  144. package/src/lib/dlp-engine.js +626 -49
  145. package/src/lib/evolution-system.js +278 -47
  146. package/src/lib/evomap-governance.js +334 -0
  147. package/src/lib/evomap-manager.js +280 -46
  148. package/src/lib/execution-backend.js +294 -48
  149. package/src/lib/feature-flags.js +294 -49
  150. package/src/lib/federation-hardening.js +340 -0
  151. package/src/lib/git-integration.js +285 -47
  152. package/src/lib/hardening-manager.js +341 -0
  153. package/src/lib/hierarchical-memory.js +284 -48
  154. package/src/lib/hook-manager.js +341 -0
  155. package/src/lib/inference-network.js +308 -51
  156. package/src/lib/instinct-manager.js +346 -0
  157. package/src/lib/ipfs-storage.js +334 -0
  158. package/src/lib/iteration-budget.js +302 -50
  159. package/src/lib/knowledge-exporter.js +341 -0
  160. package/src/lib/knowledge-graph.js +333 -0
  161. package/src/lib/knowledge-importer.js +341 -0
  162. package/src/lib/llm-providers.js +346 -0
  163. package/src/lib/matrix-bridge.js +620 -47
  164. package/src/lib/mcp-registry.js +346 -0
  165. package/src/lib/mcp-scaffold.js +318 -54
  166. package/src/lib/memory-injection.js +288 -49
  167. package/src/lib/memory-manager.js +336 -0
  168. package/src/lib/multimodal.js +330 -0
  169. package/src/lib/nl-programming.js +341 -0
  170. package/src/lib/nostr-bridge.js +622 -49
  171. package/src/lib/note-versioning.js +339 -0
  172. package/src/lib/orchestrator.js +293 -48
  173. package/src/lib/org-manager.js +336 -0
  174. package/src/lib/p2p-manager.js +341 -0
  175. package/src/lib/pdf-parser.js +298 -49
  176. package/src/lib/perception.js +346 -0
  177. package/src/lib/perf-tuning.js +309 -50
  178. package/src/lib/permanent-memory.js +327 -0
  179. package/src/lib/permission-engine.js +287 -49
  180. package/src/lib/pipeline-orchestrator.js +289 -49
  181. package/src/lib/plan-mode.js +298 -51
  182. package/src/lib/plugin-ecosystem.js +346 -0
  183. package/src/lib/pqc-manager.js +346 -0
  184. package/src/lib/privacy-computing.js +335 -0
  185. package/src/lib/protocol-fusion.js +338 -0
  186. package/src/lib/quantization.js +337 -0
  187. package/src/lib/reputation-optimizer.js +340 -0
  188. package/src/lib/response-cache.js +333 -0
  189. package/src/lib/sandbox-v2.js +327 -0
  190. package/src/lib/scim-manager.js +346 -0
  191. package/src/lib/service-container.js +313 -52
  192. package/src/lib/session-consolidator.js +296 -49
  193. package/src/lib/session-hooks.js +312 -53
  194. package/src/lib/session-manager.js +334 -0
  195. package/src/lib/session-search.js +304 -51
  196. package/src/lib/session-tail.js +288 -49
  197. package/src/lib/session-usage.js +298 -52
  198. package/src/lib/siem-exporter.js +298 -51
  199. package/src/lib/skill-loader.js +334 -0
  200. package/src/lib/skill-marketplace.js +345 -0
  201. package/src/lib/sla-manager.js +341 -0
  202. package/src/lib/slot-filler.js +303 -51
  203. package/src/lib/social-graph-analytics.js +295 -49
  204. package/src/lib/social-graph.js +272 -49
  205. package/src/lib/social-manager.js +330 -0
  206. package/src/lib/sso-manager.js +340 -0
  207. package/src/lib/stress-tester.js +342 -0
  208. package/src/lib/sub-agent-registry.js +302 -53
  209. package/src/lib/sync-manager.js +336 -0
  210. package/src/lib/task-model-selector.js +302 -50
  211. package/src/lib/tech-learning-engine.js +341 -0
  212. package/src/lib/tenant-saas.js +341 -0
  213. package/src/lib/terraform-manager.js +333 -0
  214. package/src/lib/threat-intel.js +330 -0
  215. package/src/lib/todo-manager.js +281 -47
  216. package/src/lib/token-incentive.js +341 -0
  217. package/src/lib/token-tracker.js +336 -0
  218. package/src/lib/topic-classifier.js +297 -49
  219. package/src/lib/trust-security.js +343 -0
  220. package/src/lib/ueba.js +340 -0
  221. package/src/lib/universal-runtime.js +330 -0
  222. package/src/lib/user-profile.js +294 -50
  223. package/src/lib/version-checker.js +304 -50
  224. package/src/lib/wallet-manager.js +336 -0
  225. package/src/lib/web-fetch.js +292 -51
  226. package/src/lib/workflow-engine.js +330 -0
  227. package/src/lib/zkp-engine.js +286 -49
@@ -370,25 +370,53 @@ export function _resetState() {
370
370
  _didMappings.clear();
371
371
  }
372
372
 
373
-
374
373
  // ===== V2 Surface: Nostr Bridge governance overlay (CLI v0.134.0) =====
375
374
  export const NOSTR_RELAY_MATURITY_V2 = Object.freeze({
376
- PENDING: "pending", ACTIVE: "active", OFFLINE: "offline", RETIRED: "retired",
375
+ PENDING: "pending",
376
+ ACTIVE: "active",
377
+ OFFLINE: "offline",
378
+ RETIRED: "retired",
377
379
  });
378
380
  export const NOSTR_EVENT_LIFECYCLE_V2 = Object.freeze({
379
- QUEUED: "queued", PUBLISHING: "publishing", PUBLISHED: "published", FAILED: "failed", CANCELLED: "cancelled",
381
+ QUEUED: "queued",
382
+ PUBLISHING: "publishing",
383
+ PUBLISHED: "published",
384
+ FAILED: "failed",
385
+ CANCELLED: "cancelled",
380
386
  });
381
387
 
382
388
  const _nsRelayTrans = new Map([
383
- [NOSTR_RELAY_MATURITY_V2.PENDING, new Set([NOSTR_RELAY_MATURITY_V2.ACTIVE, NOSTR_RELAY_MATURITY_V2.RETIRED])],
384
- [NOSTR_RELAY_MATURITY_V2.ACTIVE, new Set([NOSTR_RELAY_MATURITY_V2.OFFLINE, NOSTR_RELAY_MATURITY_V2.RETIRED])],
385
- [NOSTR_RELAY_MATURITY_V2.OFFLINE, new Set([NOSTR_RELAY_MATURITY_V2.ACTIVE, NOSTR_RELAY_MATURITY_V2.RETIRED])],
389
+ [
390
+ NOSTR_RELAY_MATURITY_V2.PENDING,
391
+ new Set([NOSTR_RELAY_MATURITY_V2.ACTIVE, NOSTR_RELAY_MATURITY_V2.RETIRED]),
392
+ ],
393
+ [
394
+ NOSTR_RELAY_MATURITY_V2.ACTIVE,
395
+ new Set([NOSTR_RELAY_MATURITY_V2.OFFLINE, NOSTR_RELAY_MATURITY_V2.RETIRED]),
396
+ ],
397
+ [
398
+ NOSTR_RELAY_MATURITY_V2.OFFLINE,
399
+ new Set([NOSTR_RELAY_MATURITY_V2.ACTIVE, NOSTR_RELAY_MATURITY_V2.RETIRED]),
400
+ ],
386
401
  [NOSTR_RELAY_MATURITY_V2.RETIRED, new Set()],
387
402
  ]);
388
403
  const _nsRelayTerminal = new Set([NOSTR_RELAY_MATURITY_V2.RETIRED]);
389
404
  const _nsEventTrans = new Map([
390
- [NOSTR_EVENT_LIFECYCLE_V2.QUEUED, new Set([NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING, NOSTR_EVENT_LIFECYCLE_V2.CANCELLED])],
391
- [NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING, new Set([NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED, NOSTR_EVENT_LIFECYCLE_V2.FAILED, NOSTR_EVENT_LIFECYCLE_V2.CANCELLED])],
405
+ [
406
+ NOSTR_EVENT_LIFECYCLE_V2.QUEUED,
407
+ new Set([
408
+ NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING,
409
+ NOSTR_EVENT_LIFECYCLE_V2.CANCELLED,
410
+ ]),
411
+ ],
412
+ [
413
+ NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING,
414
+ new Set([
415
+ NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED,
416
+ NOSTR_EVENT_LIFECYCLE_V2.FAILED,
417
+ NOSTR_EVENT_LIFECYCLE_V2.CANCELLED,
418
+ ]),
419
+ ],
392
420
  [NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED, new Set()],
393
421
  [NOSTR_EVENT_LIFECYCLE_V2.FAILED, new Set()],
394
422
  [NOSTR_EVENT_LIFECYCLE_V2.CANCELLED, new Set()],
@@ -401,76 +429,621 @@ let _nsMaxPendingPerRelay = 30;
401
429
  let _nsRelayIdleMs = 60 * 60 * 1000;
402
430
  let _nsEventStuckMs = 2 * 60 * 1000;
403
431
 
404
- function _nsPos(n, lbl) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${lbl} must be positive integer`); return v; }
432
+ function _nsPos(n, lbl) {
433
+ const v = Math.floor(Number(n));
434
+ if (!Number.isFinite(v) || v <= 0)
435
+ throw new Error(`${lbl} must be positive integer`);
436
+ return v;
437
+ }
405
438
 
406
- export function setMaxActiveNostrRelaysPerOwnerV2(n) { _nsMaxActivePerOwner = _nsPos(n, "maxActiveNostrRelaysPerOwner"); }
407
- export function getMaxActiveNostrRelaysPerOwnerV2() { return _nsMaxActivePerOwner; }
408
- export function setMaxPendingNostrEventsPerRelayV2(n) { _nsMaxPendingPerRelay = _nsPos(n, "maxPendingNostrEventsPerRelay"); }
409
- export function getMaxPendingNostrEventsPerRelayV2() { return _nsMaxPendingPerRelay; }
410
- export function setNostrRelayIdleMsV2(n) { _nsRelayIdleMs = _nsPos(n, "nostrRelayIdleMs"); }
411
- export function getNostrRelayIdleMsV2() { return _nsRelayIdleMs; }
412
- export function setNostrEventStuckMsV2(n) { _nsEventStuckMs = _nsPos(n, "nostrEventStuckMs"); }
413
- export function getNostrEventStuckMsV2() { return _nsEventStuckMs; }
439
+ export function setMaxActiveNostrRelaysPerOwnerV2(n) {
440
+ _nsMaxActivePerOwner = _nsPos(n, "maxActiveNostrRelaysPerOwner");
441
+ }
442
+ export function getMaxActiveNostrRelaysPerOwnerV2() {
443
+ return _nsMaxActivePerOwner;
444
+ }
445
+ export function setMaxPendingNostrEventsPerRelayV2(n) {
446
+ _nsMaxPendingPerRelay = _nsPos(n, "maxPendingNostrEventsPerRelay");
447
+ }
448
+ export function getMaxPendingNostrEventsPerRelayV2() {
449
+ return _nsMaxPendingPerRelay;
450
+ }
451
+ export function setNostrRelayIdleMsV2(n) {
452
+ _nsRelayIdleMs = _nsPos(n, "nostrRelayIdleMs");
453
+ }
454
+ export function getNostrRelayIdleMsV2() {
455
+ return _nsRelayIdleMs;
456
+ }
457
+ export function setNostrEventStuckMsV2(n) {
458
+ _nsEventStuckMs = _nsPos(n, "nostrEventStuckMs");
459
+ }
460
+ export function getNostrEventStuckMsV2() {
461
+ return _nsEventStuckMs;
462
+ }
414
463
 
415
464
  export function _resetStateNostrBridgeV2() {
416
- _nsRelays.clear(); _nsEvents.clear();
417
- _nsMaxActivePerOwner = 10; _nsMaxPendingPerRelay = 30;
418
- _nsRelayIdleMs = 60 * 60 * 1000; _nsEventStuckMs = 2 * 60 * 1000;
465
+ _nsRelays.clear();
466
+ _nsEvents.clear();
467
+ _nsMaxActivePerOwner = 10;
468
+ _nsMaxPendingPerRelay = 30;
469
+ _nsRelayIdleMs = 60 * 60 * 1000;
470
+ _nsEventStuckMs = 2 * 60 * 1000;
419
471
  }
420
472
 
421
473
  export function registerNostrRelayV2({ id, owner, url, metadata } = {}) {
422
474
  if (!id || typeof id !== "string") throw new Error("id is required");
423
475
  if (!owner || typeof owner !== "string") throw new Error("owner is required");
424
- if (_nsRelays.has(id)) throw new Error(`nostr relay ${id} already registered`);
476
+ if (_nsRelays.has(id))
477
+ throw new Error(`nostr relay ${id} already registered`);
425
478
  const now = Date.now();
426
- const r = { id, owner, url: url || "", status: NOSTR_RELAY_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, activatedAt: null, retiredAt: null, lastTouchedAt: now, metadata: { ...(metadata || {}) } };
479
+ const r = {
480
+ id,
481
+ owner,
482
+ url: url || "",
483
+ status: NOSTR_RELAY_MATURITY_V2.PENDING,
484
+ createdAt: now,
485
+ updatedAt: now,
486
+ activatedAt: null,
487
+ retiredAt: null,
488
+ lastTouchedAt: now,
489
+ metadata: { ...(metadata || {}) },
490
+ };
427
491
  _nsRelays.set(id, r);
428
492
  return { ...r, metadata: { ...r.metadata } };
429
493
  }
430
- function _nsCheckR(from, to) { const a = _nsRelayTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid nostr relay transition ${from} → ${to}`); }
431
- function _nsCountActive(owner) { let n = 0; for (const r of _nsRelays.values()) if (r.owner === owner && r.status === NOSTR_RELAY_MATURITY_V2.ACTIVE) n++; return n; }
494
+ function _nsCheckR(from, to) {
495
+ const a = _nsRelayTrans.get(from);
496
+ if (!a || !a.has(to))
497
+ throw new Error(`invalid nostr relay transition ${from} → ${to}`);
498
+ }
499
+ function _nsCountActive(owner) {
500
+ let n = 0;
501
+ for (const r of _nsRelays.values())
502
+ if (r.owner === owner && r.status === NOSTR_RELAY_MATURITY_V2.ACTIVE) n++;
503
+ return n;
504
+ }
432
505
 
433
506
  export function activateNostrRelayV2(id) {
434
- const r = _nsRelays.get(id); if (!r) throw new Error(`nostr relay ${id} not found`);
507
+ const r = _nsRelays.get(id);
508
+ if (!r) throw new Error(`nostr relay ${id} not found`);
435
509
  _nsCheckR(r.status, NOSTR_RELAY_MATURITY_V2.ACTIVE);
436
510
  const recovery = r.status === NOSTR_RELAY_MATURITY_V2.OFFLINE;
437
- if (!recovery) { const a = _nsCountActive(r.owner); if (a >= _nsMaxActivePerOwner) throw new Error(`max active nostr relays per owner (${_nsMaxActivePerOwner}) reached for ${r.owner}`); }
438
- const now = Date.now(); r.status = NOSTR_RELAY_MATURITY_V2.ACTIVE; r.updatedAt = now; r.lastTouchedAt = now; if (!r.activatedAt) r.activatedAt = now;
511
+ if (!recovery) {
512
+ const a = _nsCountActive(r.owner);
513
+ if (a >= _nsMaxActivePerOwner)
514
+ throw new Error(
515
+ `max active nostr relays per owner (${_nsMaxActivePerOwner}) reached for ${r.owner}`,
516
+ );
517
+ }
518
+ const now = Date.now();
519
+ r.status = NOSTR_RELAY_MATURITY_V2.ACTIVE;
520
+ r.updatedAt = now;
521
+ r.lastTouchedAt = now;
522
+ if (!r.activatedAt) r.activatedAt = now;
523
+ return { ...r, metadata: { ...r.metadata } };
524
+ }
525
+ export function offlineNostrRelayV2(id) {
526
+ const r = _nsRelays.get(id);
527
+ if (!r) throw new Error(`nostr relay ${id} not found`);
528
+ _nsCheckR(r.status, NOSTR_RELAY_MATURITY_V2.OFFLINE);
529
+ r.status = NOSTR_RELAY_MATURITY_V2.OFFLINE;
530
+ r.updatedAt = Date.now();
531
+ return { ...r, metadata: { ...r.metadata } };
532
+ }
533
+ export function retireNostrRelayV2(id) {
534
+ const r = _nsRelays.get(id);
535
+ if (!r) throw new Error(`nostr relay ${id} not found`);
536
+ _nsCheckR(r.status, NOSTR_RELAY_MATURITY_V2.RETIRED);
537
+ const now = Date.now();
538
+ r.status = NOSTR_RELAY_MATURITY_V2.RETIRED;
539
+ r.updatedAt = now;
540
+ if (!r.retiredAt) r.retiredAt = now;
439
541
  return { ...r, metadata: { ...r.metadata } };
440
542
  }
441
- export function offlineNostrRelayV2(id) { const r = _nsRelays.get(id); if (!r) throw new Error(`nostr relay ${id} not found`); _nsCheckR(r.status, NOSTR_RELAY_MATURITY_V2.OFFLINE); r.status = NOSTR_RELAY_MATURITY_V2.OFFLINE; r.updatedAt = Date.now(); return { ...r, metadata: { ...r.metadata } }; }
442
- export function retireNostrRelayV2(id) { const r = _nsRelays.get(id); if (!r) throw new Error(`nostr relay ${id} not found`); _nsCheckR(r.status, NOSTR_RELAY_MATURITY_V2.RETIRED); const now = Date.now(); r.status = NOSTR_RELAY_MATURITY_V2.RETIRED; r.updatedAt = now; if (!r.retiredAt) r.retiredAt = now; return { ...r, metadata: { ...r.metadata } }; }
443
- export function touchNostrRelayV2(id) { const r = _nsRelays.get(id); if (!r) throw new Error(`nostr relay ${id} not found`); if (_nsRelayTerminal.has(r.status)) throw new Error(`cannot touch terminal nostr relay ${id}`); const now = Date.now(); r.lastTouchedAt = now; r.updatedAt = now; return { ...r, metadata: { ...r.metadata } }; }
444
- export function getNostrRelayV2(id) { const r = _nsRelays.get(id); if (!r) return null; return { ...r, metadata: { ...r.metadata } }; }
445
- export function listNostrRelaysV2() { return [..._nsRelays.values()].map((r) => ({ ...r, metadata: { ...r.metadata } })); }
543
+ export function touchNostrRelayV2(id) {
544
+ const r = _nsRelays.get(id);
545
+ if (!r) throw new Error(`nostr relay ${id} not found`);
546
+ if (_nsRelayTerminal.has(r.status))
547
+ throw new Error(`cannot touch terminal nostr relay ${id}`);
548
+ const now = Date.now();
549
+ r.lastTouchedAt = now;
550
+ r.updatedAt = now;
551
+ return { ...r, metadata: { ...r.metadata } };
552
+ }
553
+ export function getNostrRelayV2(id) {
554
+ const r = _nsRelays.get(id);
555
+ if (!r) return null;
556
+ return { ...r, metadata: { ...r.metadata } };
557
+ }
558
+ export function listNostrRelaysV2() {
559
+ return [..._nsRelays.values()].map((r) => ({
560
+ ...r,
561
+ metadata: { ...r.metadata },
562
+ }));
563
+ }
446
564
 
447
- function _nsCountPending(rid) { let n = 0; for (const e of _nsEvents.values()) if (e.relayId === rid && (e.status === NOSTR_EVENT_LIFECYCLE_V2.QUEUED || e.status === NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING)) n++; return n; }
565
+ function _nsCountPending(rid) {
566
+ let n = 0;
567
+ for (const e of _nsEvents.values())
568
+ if (
569
+ e.relayId === rid &&
570
+ (e.status === NOSTR_EVENT_LIFECYCLE_V2.QUEUED ||
571
+ e.status === NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING)
572
+ )
573
+ n++;
574
+ return n;
575
+ }
448
576
 
449
577
  export function createNostrEventV2({ id, relayId, kind, metadata } = {}) {
450
578
  if (!id || typeof id !== "string") throw new Error("id is required");
451
- if (!relayId || typeof relayId !== "string") throw new Error("relayId is required");
579
+ if (!relayId || typeof relayId !== "string")
580
+ throw new Error("relayId is required");
452
581
  if (_nsEvents.has(id)) throw new Error(`nostr event ${id} already exists`);
453
- if (!_nsRelays.has(relayId)) throw new Error(`nostr relay ${relayId} not found`);
582
+ if (!_nsRelays.has(relayId))
583
+ throw new Error(`nostr relay ${relayId} not found`);
454
584
  const pending = _nsCountPending(relayId);
455
- if (pending >= _nsMaxPendingPerRelay) throw new Error(`max pending nostr events per relay (${_nsMaxPendingPerRelay}) reached for ${relayId}`);
585
+ if (pending >= _nsMaxPendingPerRelay)
586
+ throw new Error(
587
+ `max pending nostr events per relay (${_nsMaxPendingPerRelay}) reached for ${relayId}`,
588
+ );
456
589
  const now = Date.now();
457
- const e = { id, relayId, kind: typeof kind === "number" ? kind : 1, status: NOSTR_EVENT_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
590
+ const e = {
591
+ id,
592
+ relayId,
593
+ kind: typeof kind === "number" ? kind : 1,
594
+ status: NOSTR_EVENT_LIFECYCLE_V2.QUEUED,
595
+ createdAt: now,
596
+ updatedAt: now,
597
+ startedAt: null,
598
+ settledAt: null,
599
+ metadata: { ...(metadata || {}) },
600
+ };
458
601
  _nsEvents.set(id, e);
459
602
  return { ...e, metadata: { ...e.metadata } };
460
603
  }
461
- function _nsCheckE(from, to) { const a = _nsEventTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid nostr event transition ${from} → ${to}`); }
462
- export function startNostrEventV2(id) { const e = _nsEvents.get(id); if (!e) throw new Error(`nostr event ${id} not found`); _nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING); const now = Date.now(); e.status = NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING; e.updatedAt = now; if (!e.startedAt) e.startedAt = now; return { ...e, metadata: { ...e.metadata } }; }
463
- export function publishNostrEventV2(id) { const e = _nsEvents.get(id); if (!e) throw new Error(`nostr event ${id} not found`); _nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED); const now = Date.now(); e.status = NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED; e.updatedAt = now; if (!e.settledAt) e.settledAt = now; return { ...e, metadata: { ...e.metadata } }; }
464
- export function failNostrEventV2(id, reason) { const e = _nsEvents.get(id); if (!e) throw new Error(`nostr event ${id} not found`); _nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.FAILED); const now = Date.now(); e.status = NOSTR_EVENT_LIFECYCLE_V2.FAILED; e.updatedAt = now; if (!e.settledAt) e.settledAt = now; if (reason) e.metadata.failReason = String(reason); return { ...e, metadata: { ...e.metadata } }; }
465
- export function cancelNostrEventV2(id, reason) { const e = _nsEvents.get(id); if (!e) throw new Error(`nostr event ${id} not found`); _nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.CANCELLED); const now = Date.now(); e.status = NOSTR_EVENT_LIFECYCLE_V2.CANCELLED; e.updatedAt = now; if (!e.settledAt) e.settledAt = now; if (reason) e.metadata.cancelReason = String(reason); return { ...e, metadata: { ...e.metadata } }; }
466
- export function getNostrEventV2(id) { const e = _nsEvents.get(id); if (!e) return null; return { ...e, metadata: { ...e.metadata } }; }
467
- export function listNostrEventsV2() { return [..._nsEvents.values()].map((e) => ({ ...e, metadata: { ...e.metadata } })); }
604
+ function _nsCheckE(from, to) {
605
+ const a = _nsEventTrans.get(from);
606
+ if (!a || !a.has(to))
607
+ throw new Error(`invalid nostr event transition ${from} ${to}`);
608
+ }
609
+ export function startNostrEventV2(id) {
610
+ const e = _nsEvents.get(id);
611
+ if (!e) throw new Error(`nostr event ${id} not found`);
612
+ _nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING);
613
+ const now = Date.now();
614
+ e.status = NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING;
615
+ e.updatedAt = now;
616
+ if (!e.startedAt) e.startedAt = now;
617
+ return { ...e, metadata: { ...e.metadata } };
618
+ }
619
+ export function publishNostrEventV2(id) {
620
+ const e = _nsEvents.get(id);
621
+ if (!e) throw new Error(`nostr event ${id} not found`);
622
+ _nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED);
623
+ const now = Date.now();
624
+ e.status = NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED;
625
+ e.updatedAt = now;
626
+ if (!e.settledAt) e.settledAt = now;
627
+ return { ...e, metadata: { ...e.metadata } };
628
+ }
629
+ export function failNostrEventV2(id, reason) {
630
+ const e = _nsEvents.get(id);
631
+ if (!e) throw new Error(`nostr event ${id} not found`);
632
+ _nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.FAILED);
633
+ const now = Date.now();
634
+ e.status = NOSTR_EVENT_LIFECYCLE_V2.FAILED;
635
+ e.updatedAt = now;
636
+ if (!e.settledAt) e.settledAt = now;
637
+ if (reason) e.metadata.failReason = String(reason);
638
+ return { ...e, metadata: { ...e.metadata } };
639
+ }
640
+ export function cancelNostrEventV2(id, reason) {
641
+ const e = _nsEvents.get(id);
642
+ if (!e) throw new Error(`nostr event ${id} not found`);
643
+ _nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.CANCELLED);
644
+ const now = Date.now();
645
+ e.status = NOSTR_EVENT_LIFECYCLE_V2.CANCELLED;
646
+ e.updatedAt = now;
647
+ if (!e.settledAt) e.settledAt = now;
648
+ if (reason) e.metadata.cancelReason = String(reason);
649
+ return { ...e, metadata: { ...e.metadata } };
650
+ }
651
+ export function getNostrEventV2(id) {
652
+ const e = _nsEvents.get(id);
653
+ if (!e) return null;
654
+ return { ...e, metadata: { ...e.metadata } };
655
+ }
656
+ export function listNostrEventsV2() {
657
+ return [..._nsEvents.values()].map((e) => ({
658
+ ...e,
659
+ metadata: { ...e.metadata },
660
+ }));
661
+ }
468
662
 
469
- export function autoOfflineIdleNostrRelaysV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const r of _nsRelays.values()) if (r.status === NOSTR_RELAY_MATURITY_V2.ACTIVE && (t - r.lastTouchedAt) >= _nsRelayIdleMs) { r.status = NOSTR_RELAY_MATURITY_V2.OFFLINE; r.updatedAt = t; flipped.push(r.id); } return { flipped, count: flipped.length }; }
470
- export function autoFailStuckNostrEventsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const e of _nsEvents.values()) if (e.status === NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING && e.startedAt != null && (t - e.startedAt) >= _nsEventStuckMs) { e.status = NOSTR_EVENT_LIFECYCLE_V2.FAILED; e.updatedAt = t; if (!e.settledAt) e.settledAt = t; e.metadata.failReason = "auto-fail-stuck"; flipped.push(e.id); } return { flipped, count: flipped.length }; }
663
+ export function autoOfflineIdleNostrRelaysV2({ now } = {}) {
664
+ const t = now ?? Date.now();
665
+ const flipped = [];
666
+ for (const r of _nsRelays.values())
667
+ if (
668
+ r.status === NOSTR_RELAY_MATURITY_V2.ACTIVE &&
669
+ t - r.lastTouchedAt >= _nsRelayIdleMs
670
+ ) {
671
+ r.status = NOSTR_RELAY_MATURITY_V2.OFFLINE;
672
+ r.updatedAt = t;
673
+ flipped.push(r.id);
674
+ }
675
+ return { flipped, count: flipped.length };
676
+ }
677
+ export function autoFailStuckNostrEventsV2({ now } = {}) {
678
+ const t = now ?? Date.now();
679
+ const flipped = [];
680
+ for (const e of _nsEvents.values())
681
+ if (
682
+ e.status === NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING &&
683
+ e.startedAt != null &&
684
+ t - e.startedAt >= _nsEventStuckMs
685
+ ) {
686
+ e.status = NOSTR_EVENT_LIFECYCLE_V2.FAILED;
687
+ e.updatedAt = t;
688
+ if (!e.settledAt) e.settledAt = t;
689
+ e.metadata.failReason = "auto-fail-stuck";
690
+ flipped.push(e.id);
691
+ }
692
+ return { flipped, count: flipped.length };
693
+ }
471
694
 
472
695
  export function getNostrBridgeStatsV2() {
473
- const relaysByStatus = {}; for (const s of Object.values(NOSTR_RELAY_MATURITY_V2)) relaysByStatus[s] = 0; for (const r of _nsRelays.values()) relaysByStatus[r.status]++;
474
- const eventsByStatus = {}; for (const s of Object.values(NOSTR_EVENT_LIFECYCLE_V2)) eventsByStatus[s] = 0; for (const e of _nsEvents.values()) eventsByStatus[e.status]++;
475
- return { totalRelaysV2: _nsRelays.size, totalEventsV2: _nsEvents.size, maxActiveNostrRelaysPerOwner: _nsMaxActivePerOwner, maxPendingNostrEventsPerRelay: _nsMaxPendingPerRelay, nostrRelayIdleMs: _nsRelayIdleMs, nostrEventStuckMs: _nsEventStuckMs, relaysByStatus, eventsByStatus };
696
+ const relaysByStatus = {};
697
+ for (const s of Object.values(NOSTR_RELAY_MATURITY_V2)) relaysByStatus[s] = 0;
698
+ for (const r of _nsRelays.values()) relaysByStatus[r.status]++;
699
+ const eventsByStatus = {};
700
+ for (const s of Object.values(NOSTR_EVENT_LIFECYCLE_V2))
701
+ eventsByStatus[s] = 0;
702
+ for (const e of _nsEvents.values()) eventsByStatus[e.status]++;
703
+ return {
704
+ totalRelaysV2: _nsRelays.size,
705
+ totalEventsV2: _nsEvents.size,
706
+ maxActiveNostrRelaysPerOwner: _nsMaxActivePerOwner,
707
+ maxPendingNostrEventsPerRelay: _nsMaxPendingPerRelay,
708
+ nostrRelayIdleMs: _nsRelayIdleMs,
709
+ nostrEventStuckMs: _nsEventStuckMs,
710
+ relaysByStatus,
711
+ eventsByStatus,
712
+ };
713
+ }
714
+
715
+ // =====================================================================
716
+ // nostr-bridge V2 governance overlay (iter21)
717
+ // =====================================================================
718
+ export const NOSGOV_PROFILE_MATURITY_V2 = Object.freeze({
719
+ PENDING: "pending",
720
+ ACTIVE: "active",
721
+ SUSPENDED: "suspended",
722
+ ARCHIVED: "archived",
723
+ });
724
+ export const NOSGOV_PUBLISH_LIFECYCLE_V2 = Object.freeze({
725
+ QUEUED: "queued",
726
+ PUBLISHING: "publishing",
727
+ PUBLISHED: "published",
728
+ FAILED: "failed",
729
+ CANCELLED: "cancelled",
730
+ });
731
+ const _nosgovPTrans = new Map([
732
+ [
733
+ NOSGOV_PROFILE_MATURITY_V2.PENDING,
734
+ new Set([
735
+ NOSGOV_PROFILE_MATURITY_V2.ACTIVE,
736
+ NOSGOV_PROFILE_MATURITY_V2.ARCHIVED,
737
+ ]),
738
+ ],
739
+ [
740
+ NOSGOV_PROFILE_MATURITY_V2.ACTIVE,
741
+ new Set([
742
+ NOSGOV_PROFILE_MATURITY_V2.SUSPENDED,
743
+ NOSGOV_PROFILE_MATURITY_V2.ARCHIVED,
744
+ ]),
745
+ ],
746
+ [
747
+ NOSGOV_PROFILE_MATURITY_V2.SUSPENDED,
748
+ new Set([
749
+ NOSGOV_PROFILE_MATURITY_V2.ACTIVE,
750
+ NOSGOV_PROFILE_MATURITY_V2.ARCHIVED,
751
+ ]),
752
+ ],
753
+ [NOSGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
754
+ ]);
755
+ const _nosgovPTerminal = new Set([NOSGOV_PROFILE_MATURITY_V2.ARCHIVED]);
756
+ const _nosgovJTrans = new Map([
757
+ [
758
+ NOSGOV_PUBLISH_LIFECYCLE_V2.QUEUED,
759
+ new Set([
760
+ NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING,
761
+ NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED,
762
+ ]),
763
+ ],
764
+ [
765
+ NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING,
766
+ new Set([
767
+ NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHED,
768
+ NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED,
769
+ NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED,
770
+ ]),
771
+ ],
772
+ [NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHED, new Set()],
773
+ [NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED, new Set()],
774
+ [NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED, new Set()],
775
+ ]);
776
+ const _nosgovPsV2 = new Map();
777
+ const _nosgovJsV2 = new Map();
778
+ let _nosgovMaxActive = 8,
779
+ _nosgovMaxPending = 25,
780
+ _nosgovIdleMs = 30 * 24 * 60 * 60 * 1000,
781
+ _nosgovStuckMs = 60 * 1000;
782
+ function _nosgovPos(n, label) {
783
+ const v = Math.floor(Number(n));
784
+ if (!Number.isFinite(v) || v <= 0)
785
+ throw new Error(`${label} must be positive integer`);
786
+ return v;
787
+ }
788
+ function _nosgovCheckP(from, to) {
789
+ const a = _nosgovPTrans.get(from);
790
+ if (!a || !a.has(to))
791
+ throw new Error(`invalid nosgov profile transition ${from} → ${to}`);
792
+ }
793
+ function _nosgovCheckJ(from, to) {
794
+ const a = _nosgovJTrans.get(from);
795
+ if (!a || !a.has(to))
796
+ throw new Error(`invalid nosgov publish transition ${from} → ${to}`);
797
+ }
798
+ function _nosgovCountActive(owner) {
799
+ let c = 0;
800
+ for (const p of _nosgovPsV2.values())
801
+ if (p.owner === owner && p.status === NOSGOV_PROFILE_MATURITY_V2.ACTIVE)
802
+ c++;
803
+ return c;
804
+ }
805
+ function _nosgovCountPending(profileId) {
806
+ let c = 0;
807
+ for (const j of _nosgovJsV2.values())
808
+ if (
809
+ j.profileId === profileId &&
810
+ (j.status === NOSGOV_PUBLISH_LIFECYCLE_V2.QUEUED ||
811
+ j.status === NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING)
812
+ )
813
+ c++;
814
+ return c;
815
+ }
816
+ export function setMaxActiveNosgovProfilesPerOwnerV2(n) {
817
+ _nosgovMaxActive = _nosgovPos(n, "maxActiveNosgovProfilesPerOwner");
818
+ }
819
+ export function getMaxActiveNosgovProfilesPerOwnerV2() {
820
+ return _nosgovMaxActive;
821
+ }
822
+ export function setMaxPendingNosgovPublishsPerProfileV2(n) {
823
+ _nosgovMaxPending = _nosgovPos(n, "maxPendingNosgovPublishsPerProfile");
824
+ }
825
+ export function getMaxPendingNosgovPublishsPerProfileV2() {
826
+ return _nosgovMaxPending;
827
+ }
828
+ export function setNosgovProfileIdleMsV2(n) {
829
+ _nosgovIdleMs = _nosgovPos(n, "nosgovProfileIdleMs");
830
+ }
831
+ export function getNosgovProfileIdleMsV2() {
832
+ return _nosgovIdleMs;
833
+ }
834
+ export function setNosgovPublishStuckMsV2(n) {
835
+ _nosgovStuckMs = _nosgovPos(n, "nosgovPublishStuckMs");
836
+ }
837
+ export function getNosgovPublishStuckMsV2() {
838
+ return _nosgovStuckMs;
839
+ }
840
+ export function _resetStateNostrBridgeGovV2() {
841
+ _nosgovPsV2.clear();
842
+ _nosgovJsV2.clear();
843
+ _nosgovMaxActive = 8;
844
+ _nosgovMaxPending = 25;
845
+ _nosgovIdleMs = 30 * 24 * 60 * 60 * 1000;
846
+ _nosgovStuckMs = 60 * 1000;
847
+ }
848
+ export function registerNosgovProfileV2({ id, owner, relay, metadata } = {}) {
849
+ if (!id || !owner) throw new Error("id and owner required");
850
+ if (_nosgovPsV2.has(id))
851
+ throw new Error(`nosgov profile ${id} already exists`);
852
+ const now = Date.now();
853
+ const p = {
854
+ id,
855
+ owner,
856
+ relay: relay || "wss://relay.local",
857
+ status: NOSGOV_PROFILE_MATURITY_V2.PENDING,
858
+ createdAt: now,
859
+ updatedAt: now,
860
+ lastTouchedAt: now,
861
+ activatedAt: null,
862
+ archivedAt: null,
863
+ metadata: { ...(metadata || {}) },
864
+ };
865
+ _nosgovPsV2.set(id, p);
866
+ return { ...p, metadata: { ...p.metadata } };
867
+ }
868
+ export function activateNosgovProfileV2(id) {
869
+ const p = _nosgovPsV2.get(id);
870
+ if (!p) throw new Error(`nosgov profile ${id} not found`);
871
+ const isInitial = p.status === NOSGOV_PROFILE_MATURITY_V2.PENDING;
872
+ _nosgovCheckP(p.status, NOSGOV_PROFILE_MATURITY_V2.ACTIVE);
873
+ if (isInitial && _nosgovCountActive(p.owner) >= _nosgovMaxActive)
874
+ throw new Error(`max active nosgov profiles for owner ${p.owner} reached`);
875
+ const now = Date.now();
876
+ p.status = NOSGOV_PROFILE_MATURITY_V2.ACTIVE;
877
+ p.updatedAt = now;
878
+ p.lastTouchedAt = now;
879
+ if (!p.activatedAt) p.activatedAt = now;
880
+ return { ...p, metadata: { ...p.metadata } };
881
+ }
882
+ export function suspendNosgovProfileV2(id) {
883
+ const p = _nosgovPsV2.get(id);
884
+ if (!p) throw new Error(`nosgov profile ${id} not found`);
885
+ _nosgovCheckP(p.status, NOSGOV_PROFILE_MATURITY_V2.SUSPENDED);
886
+ p.status = NOSGOV_PROFILE_MATURITY_V2.SUSPENDED;
887
+ p.updatedAt = Date.now();
888
+ return { ...p, metadata: { ...p.metadata } };
889
+ }
890
+ export function archiveNosgovProfileV2(id) {
891
+ const p = _nosgovPsV2.get(id);
892
+ if (!p) throw new Error(`nosgov profile ${id} not found`);
893
+ _nosgovCheckP(p.status, NOSGOV_PROFILE_MATURITY_V2.ARCHIVED);
894
+ const now = Date.now();
895
+ p.status = NOSGOV_PROFILE_MATURITY_V2.ARCHIVED;
896
+ p.updatedAt = now;
897
+ if (!p.archivedAt) p.archivedAt = now;
898
+ return { ...p, metadata: { ...p.metadata } };
899
+ }
900
+ export function touchNosgovProfileV2(id) {
901
+ const p = _nosgovPsV2.get(id);
902
+ if (!p) throw new Error(`nosgov profile ${id} not found`);
903
+ if (_nosgovPTerminal.has(p.status))
904
+ throw new Error(`cannot touch terminal nosgov profile ${id}`);
905
+ const now = Date.now();
906
+ p.lastTouchedAt = now;
907
+ p.updatedAt = now;
908
+ return { ...p, metadata: { ...p.metadata } };
909
+ }
910
+ export function getNosgovProfileV2(id) {
911
+ const p = _nosgovPsV2.get(id);
912
+ if (!p) return null;
913
+ return { ...p, metadata: { ...p.metadata } };
914
+ }
915
+ export function listNosgovProfilesV2() {
916
+ return [..._nosgovPsV2.values()].map((p) => ({
917
+ ...p,
918
+ metadata: { ...p.metadata },
919
+ }));
920
+ }
921
+ export function createNosgovPublishV2({ id, profileId, kind, metadata } = {}) {
922
+ if (!id || !profileId) throw new Error("id and profileId required");
923
+ if (_nosgovJsV2.has(id))
924
+ throw new Error(`nosgov publish ${id} already exists`);
925
+ if (!_nosgovPsV2.has(profileId))
926
+ throw new Error(`nosgov profile ${profileId} not found`);
927
+ if (_nosgovCountPending(profileId) >= _nosgovMaxPending)
928
+ throw new Error(
929
+ `max pending nosgov publishs for profile ${profileId} reached`,
930
+ );
931
+ const now = Date.now();
932
+ const j = {
933
+ id,
934
+ profileId,
935
+ kind: kind || "",
936
+ status: NOSGOV_PUBLISH_LIFECYCLE_V2.QUEUED,
937
+ createdAt: now,
938
+ updatedAt: now,
939
+ startedAt: null,
940
+ settledAt: null,
941
+ metadata: { ...(metadata || {}) },
942
+ };
943
+ _nosgovJsV2.set(id, j);
944
+ return { ...j, metadata: { ...j.metadata } };
945
+ }
946
+ export function publishingNosgovPublishV2(id) {
947
+ const j = _nosgovJsV2.get(id);
948
+ if (!j) throw new Error(`nosgov publish ${id} not found`);
949
+ _nosgovCheckJ(j.status, NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING);
950
+ const now = Date.now();
951
+ j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING;
952
+ j.updatedAt = now;
953
+ if (!j.startedAt) j.startedAt = now;
954
+ return { ...j, metadata: { ...j.metadata } };
955
+ }
956
+ export function completePublishNosgovV2(id) {
957
+ const j = _nosgovJsV2.get(id);
958
+ if (!j) throw new Error(`nosgov publish ${id} not found`);
959
+ _nosgovCheckJ(j.status, NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHED);
960
+ const now = Date.now();
961
+ j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHED;
962
+ j.updatedAt = now;
963
+ if (!j.settledAt) j.settledAt = now;
964
+ return { ...j, metadata: { ...j.metadata } };
965
+ }
966
+ export function failNosgovPublishV2(id, reason) {
967
+ const j = _nosgovJsV2.get(id);
968
+ if (!j) throw new Error(`nosgov publish ${id} not found`);
969
+ _nosgovCheckJ(j.status, NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED);
970
+ const now = Date.now();
971
+ j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED;
972
+ j.updatedAt = now;
973
+ if (!j.settledAt) j.settledAt = now;
974
+ if (reason) j.metadata.failReason = String(reason);
975
+ return { ...j, metadata: { ...j.metadata } };
976
+ }
977
+ export function cancelNosgovPublishV2(id, reason) {
978
+ const j = _nosgovJsV2.get(id);
979
+ if (!j) throw new Error(`nosgov publish ${id} not found`);
980
+ _nosgovCheckJ(j.status, NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED);
981
+ const now = Date.now();
982
+ j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED;
983
+ j.updatedAt = now;
984
+ if (!j.settledAt) j.settledAt = now;
985
+ if (reason) j.metadata.cancelReason = String(reason);
986
+ return { ...j, metadata: { ...j.metadata } };
987
+ }
988
+ export function getNosgovPublishV2(id) {
989
+ const j = _nosgovJsV2.get(id);
990
+ if (!j) return null;
991
+ return { ...j, metadata: { ...j.metadata } };
992
+ }
993
+ export function listNosgovPublishsV2() {
994
+ return [..._nosgovJsV2.values()].map((j) => ({
995
+ ...j,
996
+ metadata: { ...j.metadata },
997
+ }));
998
+ }
999
+ export function autoSuspendIdleNosgovProfilesV2({ now } = {}) {
1000
+ const t = now ?? Date.now();
1001
+ const flipped = [];
1002
+ for (const p of _nosgovPsV2.values())
1003
+ if (
1004
+ p.status === NOSGOV_PROFILE_MATURITY_V2.ACTIVE &&
1005
+ t - p.lastTouchedAt >= _nosgovIdleMs
1006
+ ) {
1007
+ p.status = NOSGOV_PROFILE_MATURITY_V2.SUSPENDED;
1008
+ p.updatedAt = t;
1009
+ flipped.push(p.id);
1010
+ }
1011
+ return { flipped, count: flipped.length };
1012
+ }
1013
+ export function autoFailStuckNosgovPublishsV2({ now } = {}) {
1014
+ const t = now ?? Date.now();
1015
+ const flipped = [];
1016
+ for (const j of _nosgovJsV2.values())
1017
+ if (
1018
+ j.status === NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING &&
1019
+ j.startedAt != null &&
1020
+ t - j.startedAt >= _nosgovStuckMs
1021
+ ) {
1022
+ j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED;
1023
+ j.updatedAt = t;
1024
+ if (!j.settledAt) j.settledAt = t;
1025
+ j.metadata.failReason = "auto-fail-stuck";
1026
+ flipped.push(j.id);
1027
+ }
1028
+ return { flipped, count: flipped.length };
1029
+ }
1030
+ export function getNostrBridgeGovStatsV2() {
1031
+ const profilesByStatus = {};
1032
+ for (const v of Object.values(NOSGOV_PROFILE_MATURITY_V2))
1033
+ profilesByStatus[v] = 0;
1034
+ for (const p of _nosgovPsV2.values()) profilesByStatus[p.status]++;
1035
+ const publishsByStatus = {};
1036
+ for (const v of Object.values(NOSGOV_PUBLISH_LIFECYCLE_V2))
1037
+ publishsByStatus[v] = 0;
1038
+ for (const j of _nosgovJsV2.values()) publishsByStatus[j.status]++;
1039
+ return {
1040
+ totalNosgovProfilesV2: _nosgovPsV2.size,
1041
+ totalNosgovPublishsV2: _nosgovJsV2.size,
1042
+ maxActiveNosgovProfilesPerOwner: _nosgovMaxActive,
1043
+ maxPendingNosgovPublishsPerProfile: _nosgovMaxPending,
1044
+ nosgovProfileIdleMs: _nosgovIdleMs,
1045
+ nosgovPublishStuckMs: _nosgovStuckMs,
1046
+ profilesByStatus,
1047
+ publishsByStatus,
1048
+ };
476
1049
  }