chainlesschain 0.66.0 → 0.132.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 (143) hide show
  1. package/bin/chainlesschain.js +0 -0
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +380 -0
  4. package/src/commands/agent-network.js +254 -1
  5. package/src/commands/audit.js +302 -0
  6. package/src/commands/automation.js +271 -1
  7. package/src/commands/bi.js +348 -0
  8. package/src/commands/codegen.js +224 -0
  9. package/src/commands/collab.js +341 -0
  10. package/src/commands/compliance.js +1035 -0
  11. package/src/commands/cowork.js +221 -0
  12. package/src/commands/crosschain.js +218 -0
  13. package/src/commands/dbevo.js +284 -0
  14. package/src/commands/dev.js +252 -0
  15. package/src/commands/did.js +358 -0
  16. package/src/commands/dlp.js +341 -0
  17. package/src/commands/encrypt.js +341 -0
  18. package/src/commands/evomap.js +394 -0
  19. package/src/commands/export.js +256 -1
  20. package/src/commands/federation.js +283 -0
  21. package/src/commands/fusion.js +258 -0
  22. package/src/commands/governance.js +325 -0
  23. package/src/commands/hardening.js +411 -0
  24. package/src/commands/hook.js +148 -0
  25. package/src/commands/import.js +252 -0
  26. package/src/commands/incentive.js +322 -0
  27. package/src/commands/inference.js +318 -0
  28. package/src/commands/infra.js +244 -0
  29. package/src/commands/instinct.js +260 -0
  30. package/src/commands/ipfs.js +318 -0
  31. package/src/commands/kg.js +387 -0
  32. package/src/commands/llm.js +263 -0
  33. package/src/commands/lowcode.js +356 -0
  34. package/src/commands/marketplace.js +256 -0
  35. package/src/commands/mcp.js +221 -0
  36. package/src/commands/memory.js +248 -0
  37. package/src/commands/multimodal.js +296 -0
  38. package/src/commands/nlprog.js +356 -0
  39. package/src/commands/note.js +244 -0
  40. package/src/commands/ops.js +354 -0
  41. package/src/commands/orchestrate.js +166 -0
  42. package/src/commands/org.js +277 -0
  43. package/src/commands/p2p.js +390 -0
  44. package/src/commands/perception.js +290 -0
  45. package/src/commands/permmem.js +251 -0
  46. package/src/commands/plugin-ecosystem.js +273 -0
  47. package/src/commands/pqc.js +393 -0
  48. package/src/commands/privacy.js +321 -0
  49. package/src/commands/quantization.js +351 -0
  50. package/src/commands/rcache.js +271 -0
  51. package/src/commands/recommend.js +340 -0
  52. package/src/commands/reputation.js +261 -0
  53. package/src/commands/runtime.js +307 -0
  54. package/src/commands/scim.js +262 -0
  55. package/src/commands/session.js +258 -0
  56. package/src/commands/siem.js +246 -0
  57. package/src/commands/skill.js +267 -1
  58. package/src/commands/sla.js +259 -0
  59. package/src/commands/social.js +256 -0
  60. package/src/commands/sso.js +186 -1
  61. package/src/commands/stress.js +230 -0
  62. package/src/commands/sync.js +256 -0
  63. package/src/commands/tech.js +338 -0
  64. package/src/commands/tenant.js +351 -0
  65. package/src/commands/terraform.js +245 -0
  66. package/src/commands/tokens.js +269 -0
  67. package/src/commands/trust.js +249 -0
  68. package/src/commands/wallet.js +277 -0
  69. package/src/commands/workflow.js +171 -0
  70. package/src/commands/zkp.js +335 -0
  71. package/src/index.js +4 -0
  72. package/src/lib/a2a-protocol.js +451 -0
  73. package/src/lib/agent-coordinator.js +325 -0
  74. package/src/lib/agent-network.js +387 -0
  75. package/src/lib/agent-router.js +395 -0
  76. package/src/lib/aiops.js +478 -0
  77. package/src/lib/app-builder.js +239 -0
  78. package/src/lib/audit-logger.js +379 -0
  79. package/src/lib/automation-engine.js +330 -0
  80. package/src/lib/autonomous-developer.js +350 -0
  81. package/src/lib/bi-engine.js +338 -0
  82. package/src/lib/code-agent.js +323 -0
  83. package/src/lib/collaboration-governance.js +364 -0
  84. package/src/lib/community-governance.js +436 -0
  85. package/src/lib/compliance-manager.js +434 -0
  86. package/src/lib/content-recommendation.js +469 -0
  87. package/src/lib/cross-chain.js +345 -0
  88. package/src/lib/crypto-manager.js +350 -0
  89. package/src/lib/dbevo.js +338 -0
  90. package/src/lib/decentral-infra.js +340 -0
  91. package/src/lib/did-manager.js +367 -0
  92. package/src/lib/dlp-engine.js +389 -0
  93. package/src/lib/evomap-federation.js +177 -0
  94. package/src/lib/evomap-governance.js +276 -0
  95. package/src/lib/federation-hardening.js +259 -0
  96. package/src/lib/hardening-manager.js +348 -0
  97. package/src/lib/hook-manager.js +380 -0
  98. package/src/lib/inference-network.js +330 -0
  99. package/src/lib/instinct-manager.js +332 -0
  100. package/src/lib/ipfs-storage.js +334 -0
  101. package/src/lib/knowledge-exporter.js +381 -0
  102. package/src/lib/knowledge-graph.js +432 -0
  103. package/src/lib/knowledge-importer.js +379 -0
  104. package/src/lib/llm-providers.js +391 -0
  105. package/src/lib/mcp-registry.js +333 -0
  106. package/src/lib/memory-manager.js +330 -0
  107. package/src/lib/multimodal.js +346 -0
  108. package/src/lib/nl-programming.js +343 -0
  109. package/src/lib/note-versioning.js +327 -0
  110. package/src/lib/org-manager.js +323 -0
  111. package/src/lib/p2p-manager.js +387 -0
  112. package/src/lib/perception.js +346 -0
  113. package/src/lib/perf-tuning.js +4 -1
  114. package/src/lib/permanent-memory.js +320 -0
  115. package/src/lib/plugin-ecosystem.js +377 -0
  116. package/src/lib/pqc-manager.js +368 -0
  117. package/src/lib/privacy-computing.js +427 -0
  118. package/src/lib/protocol-fusion.js +417 -0
  119. package/src/lib/quantization.js +325 -0
  120. package/src/lib/reputation-optimizer.js +299 -0
  121. package/src/lib/response-cache.js +327 -0
  122. package/src/lib/scim-manager.js +329 -0
  123. package/src/lib/session-manager.js +329 -0
  124. package/src/lib/siem-exporter.js +333 -0
  125. package/src/lib/skill-loader.js +377 -0
  126. package/src/lib/skill-marketplace.js +325 -0
  127. package/src/lib/sla-manager.js +275 -0
  128. package/src/lib/social-manager.js +326 -0
  129. package/src/lib/sso-manager.js +332 -0
  130. package/src/lib/stress-tester.js +330 -0
  131. package/src/lib/sync-manager.js +326 -0
  132. package/src/lib/tech-learning-engine.js +369 -0
  133. package/src/lib/tenant-saas.js +460 -0
  134. package/src/lib/terraform-manager.js +363 -0
  135. package/src/lib/threat-intel.js +335 -0
  136. package/src/lib/token-incentive.js +293 -0
  137. package/src/lib/token-tracker.js +329 -0
  138. package/src/lib/trust-security.js +390 -0
  139. package/src/lib/ueba.js +389 -0
  140. package/src/lib/universal-runtime.js +325 -0
  141. package/src/lib/wallet-manager.js +326 -0
  142. package/src/lib/workflow-engine.js +322 -0
  143. package/src/lib/zkp-engine.js +274 -0
@@ -297,3 +297,341 @@ export function _resetState() {
297
297
  _reports.clear();
298
298
  _scheduledReports.clear();
299
299
  }
300
+
301
+ // ─── Phase 95 V2 surface (strictly additive) ───────────────────────
302
+
303
+ export const CHART_TYPE = Object.freeze({
304
+ TABLE: "table",
305
+ BAR: "bar",
306
+ LINE: "line",
307
+ PIE: "pie",
308
+ AREA: "area",
309
+ SCATTER: "scatter",
310
+ HEATMAP: "heatmap",
311
+ FUNNEL: "funnel",
312
+ GAUGE: "gauge",
313
+ });
314
+
315
+ export const ANOMALY_METHOD = Object.freeze({
316
+ Z_SCORE: "z_score",
317
+ IQR: "iqr",
318
+ });
319
+
320
+ export const REPORT_FORMAT = Object.freeze({
321
+ PDF: "pdf",
322
+ EXCEL: "excel",
323
+ CSV: "csv",
324
+ JSON: "json",
325
+ });
326
+
327
+ export const REPORT_STATUS = Object.freeze({
328
+ DRAFT: "draft",
329
+ GENERATED: "generated",
330
+ SCHEDULED: "scheduled",
331
+ ARCHIVED: "archived",
332
+ });
333
+
334
+ export const DASHBOARD_LAYOUT = Object.freeze({
335
+ GRID: "grid",
336
+ FLOW: "flow",
337
+ TABS: "tabs",
338
+ });
339
+
340
+ const _reportStatusV2 = new Map();
341
+ const _statusHistoryV2 = new Map();
342
+
343
+ const _allowedReportTransitions = Object.freeze({
344
+ draft: new Set(["generated", "archived"]),
345
+ generated: new Set(["scheduled", "archived", "draft"]),
346
+ scheduled: new Set(["generated", "archived"]),
347
+ archived: new Set(["draft"]),
348
+ });
349
+
350
+ function _quantile(sorted, q) {
351
+ if (sorted.length === 0) return NaN;
352
+ const pos = (sorted.length - 1) * q;
353
+ const lo = Math.floor(pos);
354
+ const hi = Math.ceil(pos);
355
+ if (lo === hi) return sorted[lo];
356
+ return sorted[lo] + (pos - lo) * (sorted[hi] - sorted[lo]);
357
+ }
358
+
359
+ export function nlQueryV2({ query, schema } = {}) {
360
+ if (!query || typeof query !== "string") {
361
+ throw new Error("query must be a non-empty string");
362
+ }
363
+ const normalized = query.replace(/['"]/g, "").trim().toLowerCase();
364
+ const tokens = normalized.split(/\s+/);
365
+
366
+ // Detect table name from schema (first match) or fall back to "data"
367
+ let table = "data";
368
+ const knownTables =
369
+ schema && Array.isArray(schema.tables)
370
+ ? schema.tables.map((t) => String(t).toLowerCase())
371
+ : [];
372
+ for (const t of knownTables) {
373
+ if (tokens.includes(t)) {
374
+ table = t;
375
+ break;
376
+ }
377
+ }
378
+
379
+ // Detect aggregate intent
380
+ let aggregate = null;
381
+ let intent = "list";
382
+ let visualization = CHART_TYPE.TABLE;
383
+
384
+ if (/\b(count|how many)\b/.test(normalized)) {
385
+ aggregate = "COUNT(*)";
386
+ intent = "count";
387
+ visualization = CHART_TYPE.BAR;
388
+ } else if (/\b(sum|total)\b/.test(normalized)) {
389
+ aggregate = "SUM(value)";
390
+ intent = "sum";
391
+ visualization = CHART_TYPE.GAUGE;
392
+ } else if (/\b(avg|average|mean)\b/.test(normalized)) {
393
+ aggregate = "AVG(value)";
394
+ intent = "avg";
395
+ visualization = CHART_TYPE.GAUGE;
396
+ } else if (/\b(trend|over time|timeline|history)\b/.test(normalized)) {
397
+ intent = "trend";
398
+ visualization = CHART_TYPE.LINE;
399
+ } else if (/\b(distribution|breakdown)\b/.test(normalized)) {
400
+ intent = "distribution";
401
+ visualization = CHART_TYPE.PIE;
402
+ }
403
+
404
+ // Detect top N
405
+ let limit = null;
406
+ const topMatch = normalized.match(/\btop\s+(\d+)\b/);
407
+ if (topMatch) {
408
+ limit = parseInt(topMatch[1], 10);
409
+ if (intent === "list") {
410
+ intent = "top";
411
+ visualization = CHART_TYPE.BAR;
412
+ }
413
+ }
414
+
415
+ // Build SQL
416
+ let sql;
417
+ if (aggregate) {
418
+ sql = `SELECT ${aggregate} FROM ${table}`;
419
+ } else {
420
+ sql = `SELECT * FROM ${table}`;
421
+ }
422
+ if (limit !== null) {
423
+ sql += ` ORDER BY value DESC LIMIT ${limit}`;
424
+ } else if (intent === "trend") {
425
+ sql += ` ORDER BY created_at ASC`;
426
+ }
427
+
428
+ return {
429
+ id: crypto.randomUUID(),
430
+ query,
431
+ intent,
432
+ sql,
433
+ table,
434
+ aggregate,
435
+ limit,
436
+ visualization,
437
+ };
438
+ }
439
+
440
+ export function detectAnomalyV2({
441
+ data,
442
+ method = ANOMALY_METHOD.Z_SCORE,
443
+ threshold,
444
+ } = {}) {
445
+ if (!Array.isArray(data) || data.length === 0) {
446
+ throw new Error("data must be a non-empty array of numbers");
447
+ }
448
+ const valid = Object.values(ANOMALY_METHOD);
449
+ if (!valid.includes(method)) {
450
+ throw new Error(
451
+ `Invalid method '${method}'. Expected one of ${valid.join(", ")}`,
452
+ );
453
+ }
454
+
455
+ if (method === ANOMALY_METHOD.Z_SCORE) {
456
+ const t = threshold == null ? 2 : threshold;
457
+ const legacy = detectAnomaly(data, { threshold: t });
458
+ return { method, threshold: t, ...legacy };
459
+ }
460
+
461
+ // IQR method
462
+ const sorted = [...data].sort((a, b) => a - b);
463
+ const q1 = _quantile(sorted, 0.25);
464
+ const q3 = _quantile(sorted, 0.75);
465
+ const iqr = q3 - q1;
466
+ const multiplier = threshold == null ? 1.5 : threshold;
467
+ const lowerBound = q1 - multiplier * iqr;
468
+ const upperBound = q3 + multiplier * iqr;
469
+
470
+ const anomalies = [];
471
+ for (let i = 0; i < data.length; i++) {
472
+ if (data[i] < lowerBound || data[i] > upperBound) {
473
+ anomalies.push({ index: i, value: data[i] });
474
+ }
475
+ }
476
+
477
+ return {
478
+ method,
479
+ threshold: multiplier,
480
+ q1,
481
+ q3,
482
+ iqr,
483
+ lowerBound,
484
+ upperBound,
485
+ anomalies,
486
+ };
487
+ }
488
+
489
+ export function predictTrendV2({ data, periods = 3, method = "linear" } = {}) {
490
+ if (!Array.isArray(data) || data.length < 2) {
491
+ throw new Error("data must be an array with at least 2 points");
492
+ }
493
+ if (method !== "linear") {
494
+ throw new Error(`Invalid method '${method}'. Only 'linear' is supported`);
495
+ }
496
+
497
+ const legacy = predictTrend(data, periods);
498
+
499
+ // Compute R² (coefficient of determination)
500
+ const n = data.length;
501
+ const meanY = data.reduce((s, v) => s + v, 0) / n;
502
+ let ssRes = 0;
503
+ let ssTot = 0;
504
+ for (let i = 0; i < n; i++) {
505
+ const predicted = legacy.slope * i + (meanY - legacy.slope * ((n - 1) / 2));
506
+ ssRes += (data[i] - predicted) ** 2;
507
+ ssTot += (data[i] - meanY) ** 2;
508
+ }
509
+ let r2 = ssTot === 0 ? 1 : 1 - ssRes / ssTot;
510
+ if (r2 < 0) r2 = 0;
511
+ if (r2 > 1) r2 = 1;
512
+
513
+ return {
514
+ method,
515
+ ...legacy,
516
+ r2: Math.round(r2 * 1000) / 1000,
517
+ confidence: r2 >= 0.7 ? "high" : r2 >= 0.4 ? "medium" : "low",
518
+ };
519
+ }
520
+
521
+ export function recommendChart({ intent, dataShape } = {}) {
522
+ if (intent) {
523
+ const i = String(intent).toLowerCase();
524
+ if (i.includes("trend") || i.includes("time")) return CHART_TYPE.LINE;
525
+ if (i.includes("distribution") || i.includes("share"))
526
+ return CHART_TYPE.PIE;
527
+ if (i.includes("compare") || i.includes("top")) return CHART_TYPE.BAR;
528
+ if (i.includes("correlation")) return CHART_TYPE.SCATTER;
529
+ if (i.includes("funnel")) return CHART_TYPE.FUNNEL;
530
+ if (i.includes("heat")) return CHART_TYPE.HEATMAP;
531
+ if (i.includes("gauge") || i.includes("kpi")) return CHART_TYPE.GAUGE;
532
+ }
533
+ if (dataShape) {
534
+ if (dataShape.dimensions === 1 && dataShape.categorical)
535
+ return CHART_TYPE.PIE;
536
+ if (dataShape.timeseries) return CHART_TYPE.LINE;
537
+ if (dataShape.dimensions === 2) return CHART_TYPE.SCATTER;
538
+ }
539
+ return CHART_TYPE.TABLE;
540
+ }
541
+
542
+ export function createDashboardV2(db, { name, widgets = [], layout } = {}) {
543
+ if (!name) throw new Error("name is required");
544
+ let layoutSpec;
545
+ if (!layout) {
546
+ layoutSpec = { type: DASHBOARD_LAYOUT.GRID, columns: 2 };
547
+ } else if (typeof layout === "string") {
548
+ const valid = Object.values(DASHBOARD_LAYOUT);
549
+ if (!valid.includes(layout)) {
550
+ throw new Error(
551
+ `Invalid layout '${layout}'. Expected one of ${valid.join(", ")}`,
552
+ );
553
+ }
554
+ layoutSpec = { type: layout, columns: 2 };
555
+ } else {
556
+ const type = layout.type || DASHBOARD_LAYOUT.GRID;
557
+ const valid = Object.values(DASHBOARD_LAYOUT);
558
+ if (!valid.includes(type)) {
559
+ throw new Error(
560
+ `Invalid layout type '${type}'. Expected one of ${valid.join(", ")}`,
561
+ );
562
+ }
563
+ layoutSpec = { ...layout, type };
564
+ }
565
+ return createDashboard(db, name, widgets, layoutSpec);
566
+ }
567
+
568
+ export function updateReportStatus(db, { reportId, status } = {}) {
569
+ const valid = Object.values(REPORT_STATUS);
570
+ if (!valid.includes(status)) {
571
+ throw new Error(
572
+ `Invalid status '${status}'. Expected one of ${valid.join(", ")}`,
573
+ );
574
+ }
575
+ const current = _reportStatusV2.get(reportId) || REPORT_STATUS.DRAFT;
576
+ const allowed = _allowedReportTransitions[current];
577
+ if (!allowed.has(status) && current !== status) {
578
+ throw new Error(`Invalid status transition: ${current} → ${status}`);
579
+ }
580
+ _reportStatusV2.set(reportId, status);
581
+ const hist = _statusHistoryV2.get(reportId) || [];
582
+ hist.push({
583
+ from: current,
584
+ to: status,
585
+ at: new Date().toISOString(),
586
+ });
587
+ _statusHistoryV2.set(reportId, hist);
588
+ return { reportId, status, previous: current };
589
+ }
590
+
591
+ export function getReportStatus(reportId) {
592
+ return _reportStatusV2.get(reportId) || REPORT_STATUS.DRAFT;
593
+ }
594
+
595
+ export function getReportStatusHistory(reportId) {
596
+ return (_statusHistoryV2.get(reportId) || []).slice();
597
+ }
598
+
599
+ export function getBIStatsV2(db) {
600
+ const dashboards = db.prepare(`SELECT id FROM bi_dashboards`).all();
601
+ const reports = db.prepare(`SELECT id, format FROM bi_reports`).all();
602
+ const scheduled = db.prepare(`SELECT id FROM bi_scheduled`).all();
603
+
604
+ const byStatus = {
605
+ draft: 0,
606
+ generated: 0,
607
+ scheduled: 0,
608
+ archived: 0,
609
+ };
610
+ for (const r of reports) {
611
+ const s = _reportStatusV2.get(r.id) || REPORT_STATUS.DRAFT;
612
+ byStatus[s] = (byStatus[s] || 0) + 1;
613
+ }
614
+
615
+ const byFormat = {};
616
+ for (const r of reports) {
617
+ const f = r.format || "pdf";
618
+ byFormat[f] = (byFormat[f] || 0) + 1;
619
+ }
620
+
621
+ return {
622
+ dashboards: dashboards.length,
623
+ reports: {
624
+ total: reports.length,
625
+ byStatus,
626
+ byFormat,
627
+ },
628
+ scheduled: scheduled.length,
629
+ templates: _templates.length,
630
+ chartTypes: Object.values(CHART_TYPE).length,
631
+ };
632
+ }
633
+
634
+ export function _resetV2State() {
635
+ _reportStatusV2.clear();
636
+ _statusHistoryV2.clear();
637
+ }
@@ -440,3 +440,326 @@ export function _resetState() {
440
440
  _reviews.clear();
441
441
  _scaffolds.clear();
442
442
  }
443
+
444
+ /* ═════════════════════════════════════════════════════════ *
445
+ * Phase 86 V2 — Code Agent Maturity + Generation Job
446
+ * ═════════════════════════════════════════════════════════ */
447
+
448
+ export const AGENT_MATURITY_V2 = Object.freeze({
449
+ DRAFT: "draft",
450
+ ACTIVE: "active",
451
+ DEPRECATED: "deprecated",
452
+ RETIRED: "retired",
453
+ });
454
+
455
+ export const GEN_JOB_V2 = Object.freeze({
456
+ QUEUED: "queued",
457
+ RUNNING: "running",
458
+ SUCCEEDED: "succeeded",
459
+ FAILED: "failed",
460
+ CANCELED: "canceled",
461
+ });
462
+
463
+ const AGENT_TRANSITIONS_V2 = new Map([
464
+ ["draft", new Set(["active", "retired"])],
465
+ ["active", new Set(["deprecated", "retired"])],
466
+ ["deprecated", new Set(["active", "retired"])],
467
+ ]);
468
+ const AGENT_TERMINALS_V2 = new Set(["retired"]);
469
+
470
+ const JOB_TRANSITIONS_V2 = new Map([
471
+ ["queued", new Set(["running", "canceled", "failed"])],
472
+ ["running", new Set(["succeeded", "failed", "canceled"])],
473
+ ]);
474
+ const JOB_TERMINALS_V2 = new Set(["succeeded", "failed", "canceled"]);
475
+
476
+ export const CGA_DEFAULT_MAX_ACTIVE_AGENTS_PER_OWNER = 15;
477
+ export const CGA_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER = 3;
478
+ export const CGA_DEFAULT_AGENT_IDLE_MS = 60 * 86400000; // 60 days
479
+ export const CGA_DEFAULT_JOB_STUCK_MS = 15 * 60000; // 15 minutes
480
+
481
+ let _maxActiveAgentsPerOwnerV2 = CGA_DEFAULT_MAX_ACTIVE_AGENTS_PER_OWNER;
482
+ let _maxRunningJobsPerOwnerV2 = CGA_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
483
+ let _agentIdleMsV2 = CGA_DEFAULT_AGENT_IDLE_MS;
484
+ let _jobStuckMsV2 = CGA_DEFAULT_JOB_STUCK_MS;
485
+
486
+ function _positiveIntV2(n, label) {
487
+ const v = Math.floor(Number(n));
488
+ if (!Number.isFinite(v) || v <= 0)
489
+ throw new Error(`${label} must be a positive integer`);
490
+ return v;
491
+ }
492
+
493
+ export function getDefaultMaxActiveAgentsPerOwnerV2() {
494
+ return CGA_DEFAULT_MAX_ACTIVE_AGENTS_PER_OWNER;
495
+ }
496
+ export function getMaxActiveAgentsPerOwnerV2() {
497
+ return _maxActiveAgentsPerOwnerV2;
498
+ }
499
+ export function setMaxActiveAgentsPerOwnerV2(n) {
500
+ return (_maxActiveAgentsPerOwnerV2 = _positiveIntV2(
501
+ n,
502
+ "maxActiveAgentsPerOwner",
503
+ ));
504
+ }
505
+ export function getDefaultMaxRunningJobsPerOwnerV2() {
506
+ return CGA_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
507
+ }
508
+ export function getMaxRunningJobsPerOwnerV2() {
509
+ return _maxRunningJobsPerOwnerV2;
510
+ }
511
+ export function setMaxRunningJobsPerOwnerV2(n) {
512
+ return (_maxRunningJobsPerOwnerV2 = _positiveIntV2(
513
+ n,
514
+ "maxRunningJobsPerOwner",
515
+ ));
516
+ }
517
+ export function getDefaultAgentIdleMsV2() {
518
+ return CGA_DEFAULT_AGENT_IDLE_MS;
519
+ }
520
+ export function getAgentIdleMsV2() {
521
+ return _agentIdleMsV2;
522
+ }
523
+ export function setAgentIdleMsV2(ms) {
524
+ return (_agentIdleMsV2 = _positiveIntV2(ms, "agentIdleMs"));
525
+ }
526
+ export function getDefaultJobStuckMsV2() {
527
+ return CGA_DEFAULT_JOB_STUCK_MS;
528
+ }
529
+ export function getJobStuckMsV2() {
530
+ return _jobStuckMsV2;
531
+ }
532
+ export function setJobStuckMsV2(ms) {
533
+ return (_jobStuckMsV2 = _positiveIntV2(ms, "jobStuckMs"));
534
+ }
535
+
536
+ const _agentsV2 = new Map();
537
+ const _jobsV2 = new Map();
538
+
539
+ export function registerAgentV2(
540
+ _db,
541
+ { agentId, ownerId, name, initialStatus, metadata } = {},
542
+ ) {
543
+ if (!agentId) throw new Error("agentId is required");
544
+ if (!ownerId) throw new Error("ownerId is required");
545
+ if (_agentsV2.has(agentId))
546
+ throw new Error(`Agent ${agentId} already exists`);
547
+ const status = initialStatus || AGENT_MATURITY_V2.DRAFT;
548
+ if (!Object.values(AGENT_MATURITY_V2).includes(status))
549
+ throw new Error(`Invalid initial status: ${status}`);
550
+ if (AGENT_TERMINALS_V2.has(status))
551
+ throw new Error(`Cannot register in terminal status: ${status}`);
552
+ if (status === AGENT_MATURITY_V2.ACTIVE) {
553
+ if (getActiveAgentCount(ownerId) >= _maxActiveAgentsPerOwnerV2)
554
+ throw new Error(
555
+ `Owner ${ownerId} reached active-agent cap (${_maxActiveAgentsPerOwnerV2})`,
556
+ );
557
+ }
558
+ const now = Date.now();
559
+ const record = {
560
+ agentId,
561
+ ownerId,
562
+ name: name || agentId,
563
+ status,
564
+ metadata: metadata || {},
565
+ createdAt: now,
566
+ updatedAt: now,
567
+ lastInvokedAt: now,
568
+ };
569
+ _agentsV2.set(agentId, record);
570
+ return { ...record, metadata: { ...record.metadata } };
571
+ }
572
+
573
+ export function getAgentV2(agentId) {
574
+ const r = _agentsV2.get(agentId);
575
+ return r ? { ...r, metadata: { ...r.metadata } } : null;
576
+ }
577
+
578
+ export function setAgentMaturityV2(_db, agentId, newStatus, patch = {}) {
579
+ const record = _agentsV2.get(agentId);
580
+ if (!record) throw new Error(`Unknown agent: ${agentId}`);
581
+ if (!Object.values(AGENT_MATURITY_V2).includes(newStatus))
582
+ throw new Error(`Invalid status: ${newStatus}`);
583
+ const allowed = AGENT_TRANSITIONS_V2.get(record.status) || new Set();
584
+ if (!allowed.has(newStatus))
585
+ throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
586
+ if (newStatus === AGENT_MATURITY_V2.ACTIVE) {
587
+ if (getActiveAgentCount(record.ownerId) >= _maxActiveAgentsPerOwnerV2)
588
+ throw new Error(
589
+ `Owner ${record.ownerId} reached active-agent cap (${_maxActiveAgentsPerOwnerV2})`,
590
+ );
591
+ }
592
+ record.status = newStatus;
593
+ record.updatedAt = Date.now();
594
+ if (patch.reason !== undefined) record.lastReason = patch.reason;
595
+ if (patch.metadata)
596
+ record.metadata = { ...record.metadata, ...patch.metadata };
597
+ return { ...record, metadata: { ...record.metadata } };
598
+ }
599
+
600
+ export function activateAgent(db, id, reason) {
601
+ return setAgentMaturityV2(db, id, AGENT_MATURITY_V2.ACTIVE, { reason });
602
+ }
603
+ export function deprecateAgent(db, id, reason) {
604
+ return setAgentMaturityV2(db, id, AGENT_MATURITY_V2.DEPRECATED, { reason });
605
+ }
606
+ export function retireAgent(db, id, reason) {
607
+ return setAgentMaturityV2(db, id, AGENT_MATURITY_V2.RETIRED, { reason });
608
+ }
609
+
610
+ export function touchAgentInvocation(agentId) {
611
+ const record = _agentsV2.get(agentId);
612
+ if (!record) throw new Error(`Unknown agent: ${agentId}`);
613
+ record.lastInvokedAt = Date.now();
614
+ record.updatedAt = record.lastInvokedAt;
615
+ return { ...record, metadata: { ...record.metadata } };
616
+ }
617
+
618
+ export function enqueueGenJobV2(
619
+ _db,
620
+ { jobId, ownerId, agentId, prompt, metadata } = {},
621
+ ) {
622
+ if (!jobId) throw new Error("jobId is required");
623
+ if (!ownerId) throw new Error("ownerId is required");
624
+ if (!agentId) throw new Error("agentId is required");
625
+ if (!prompt) throw new Error("prompt is required");
626
+ if (_jobsV2.has(jobId)) throw new Error(`Job ${jobId} already exists`);
627
+ const now = Date.now();
628
+ const record = {
629
+ jobId,
630
+ ownerId,
631
+ agentId,
632
+ prompt,
633
+ status: GEN_JOB_V2.QUEUED,
634
+ metadata: metadata || {},
635
+ createdAt: now,
636
+ updatedAt: now,
637
+ };
638
+ _jobsV2.set(jobId, record);
639
+ return { ...record, metadata: { ...record.metadata } };
640
+ }
641
+
642
+ export function getGenJobV2(jobId) {
643
+ const r = _jobsV2.get(jobId);
644
+ return r ? { ...r, metadata: { ...r.metadata } } : null;
645
+ }
646
+
647
+ export function setGenJobStatusV2(_db, jobId, newStatus, patch = {}) {
648
+ const record = _jobsV2.get(jobId);
649
+ if (!record) throw new Error(`Unknown job: ${jobId}`);
650
+ if (!Object.values(GEN_JOB_V2).includes(newStatus))
651
+ throw new Error(`Invalid status: ${newStatus}`);
652
+ const allowed = JOB_TRANSITIONS_V2.get(record.status) || new Set();
653
+ if (!allowed.has(newStatus))
654
+ throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
655
+ if (newStatus === GEN_JOB_V2.RUNNING) {
656
+ if (getRunningJobCount(record.ownerId) >= _maxRunningJobsPerOwnerV2)
657
+ throw new Error(
658
+ `Owner ${record.ownerId} reached running-job cap (${_maxRunningJobsPerOwnerV2})`,
659
+ );
660
+ if (!record.startedAt) record.startedAt = Date.now();
661
+ }
662
+ record.status = newStatus;
663
+ record.updatedAt = Date.now();
664
+ if (patch.reason !== undefined) record.lastReason = patch.reason;
665
+ if (patch.metadata)
666
+ record.metadata = { ...record.metadata, ...patch.metadata };
667
+ return { ...record, metadata: { ...record.metadata } };
668
+ }
669
+
670
+ export function startGenJob(db, id, reason) {
671
+ return setGenJobStatusV2(db, id, GEN_JOB_V2.RUNNING, { reason });
672
+ }
673
+ export function succeedGenJob(db, id, reason) {
674
+ return setGenJobStatusV2(db, id, GEN_JOB_V2.SUCCEEDED, { reason });
675
+ }
676
+ export function failGenJob(db, id, reason) {
677
+ return setGenJobStatusV2(db, id, GEN_JOB_V2.FAILED, { reason });
678
+ }
679
+ export function cancelGenJob(db, id, reason) {
680
+ return setGenJobStatusV2(db, id, GEN_JOB_V2.CANCELED, { reason });
681
+ }
682
+
683
+ export function getActiveAgentCount(ownerId) {
684
+ let n = 0;
685
+ for (const r of _agentsV2.values()) {
686
+ if (r.status !== AGENT_MATURITY_V2.ACTIVE) continue;
687
+ if (ownerId && r.ownerId !== ownerId) continue;
688
+ n++;
689
+ }
690
+ return n;
691
+ }
692
+
693
+ export function getRunningJobCount(ownerId) {
694
+ let n = 0;
695
+ for (const r of _jobsV2.values()) {
696
+ if (r.status !== GEN_JOB_V2.RUNNING) continue;
697
+ if (ownerId && r.ownerId !== ownerId) continue;
698
+ n++;
699
+ }
700
+ return n;
701
+ }
702
+
703
+ export function autoRetireIdleAgents(_db, nowMs) {
704
+ const now = nowMs ?? Date.now();
705
+ const flipped = [];
706
+ for (const r of _agentsV2.values()) {
707
+ if (
708
+ r.status === AGENT_MATURITY_V2.ACTIVE ||
709
+ r.status === AGENT_MATURITY_V2.DEPRECATED
710
+ ) {
711
+ if (now - r.lastInvokedAt > _agentIdleMsV2) {
712
+ r.status = AGENT_MATURITY_V2.RETIRED;
713
+ r.updatedAt = now;
714
+ r.lastReason = "idle_timeout";
715
+ flipped.push(r.agentId);
716
+ }
717
+ }
718
+ }
719
+ return { flipped, count: flipped.length };
720
+ }
721
+
722
+ export function autoFailStuckGenJobs(_db, nowMs) {
723
+ const now = nowMs ?? Date.now();
724
+ const flipped = [];
725
+ for (const r of _jobsV2.values()) {
726
+ if (r.status === GEN_JOB_V2.RUNNING) {
727
+ const anchor = r.startedAt || r.createdAt;
728
+ if (now - anchor > _jobStuckMsV2) {
729
+ r.status = GEN_JOB_V2.FAILED;
730
+ r.updatedAt = now;
731
+ r.lastReason = "job_timeout";
732
+ flipped.push(r.jobId);
733
+ }
734
+ }
735
+ }
736
+ return { flipped, count: flipped.length };
737
+ }
738
+
739
+ export function getCodeAgentStatsV2() {
740
+ const agentsByStatus = {};
741
+ for (const s of Object.values(AGENT_MATURITY_V2)) agentsByStatus[s] = 0;
742
+ const jobsByStatus = {};
743
+ for (const s of Object.values(GEN_JOB_V2)) jobsByStatus[s] = 0;
744
+ for (const r of _agentsV2.values()) agentsByStatus[r.status]++;
745
+ for (const r of _jobsV2.values()) jobsByStatus[r.status]++;
746
+ return {
747
+ totalAgentsV2: _agentsV2.size,
748
+ totalJobsV2: _jobsV2.size,
749
+ maxActiveAgentsPerOwner: _maxActiveAgentsPerOwnerV2,
750
+ maxRunningJobsPerOwner: _maxRunningJobsPerOwnerV2,
751
+ agentIdleMs: _agentIdleMsV2,
752
+ jobStuckMs: _jobStuckMsV2,
753
+ agentsByStatus,
754
+ jobsByStatus,
755
+ };
756
+ }
757
+
758
+ export function _resetStateV2() {
759
+ _maxActiveAgentsPerOwnerV2 = CGA_DEFAULT_MAX_ACTIVE_AGENTS_PER_OWNER;
760
+ _maxRunningJobsPerOwnerV2 = CGA_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
761
+ _agentIdleMsV2 = CGA_DEFAULT_AGENT_IDLE_MS;
762
+ _jobStuckMsV2 = CGA_DEFAULT_JOB_STUCK_MS;
763
+ _agentsV2.clear();
764
+ _jobsV2.clear();
765
+ }