chainlesschain 0.143.0 → 0.145.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 (133) hide show
  1. package/package.json +1 -1
  2. package/src/commands/a2a.js +196 -28
  3. package/src/commands/activitypub.js +157 -27
  4. package/src/commands/agent.js +587 -103
  5. package/src/commands/audit.js +206 -0
  6. package/src/commands/bi.js +152 -27
  7. package/src/commands/bm25.js +111 -27
  8. package/src/commands/browse.js +190 -29
  9. package/src/commands/ccron.js +128 -28
  10. package/src/commands/chat.js +207 -0
  11. package/src/commands/compliance.js +414 -34
  12. package/src/commands/compt.js +127 -29
  13. package/src/commands/consol.js +8 -2
  14. package/src/commands/cowork.js +580 -34
  15. package/src/commands/crosschain.js +182 -28
  16. package/src/commands/dao.js +182 -28
  17. package/src/commands/dlp.js +172 -27
  18. package/src/commands/economy.js +205 -50
  19. package/src/commands/evolution.js +203 -50
  20. package/src/commands/evomap.js +182 -27
  21. package/src/commands/fflag.js +74 -22
  22. package/src/commands/git.js +177 -37
  23. package/src/commands/hardening.js +209 -0
  24. package/src/commands/hmemory.js +204 -50
  25. package/src/commands/incentive.js +209 -0
  26. package/src/commands/inference.js +170 -34
  27. package/src/commands/itbudget.js +149 -33
  28. package/src/commands/kg.js +206 -0
  29. package/src/commands/lowcode.js +195 -38
  30. package/src/commands/marketplace.js +206 -0
  31. package/src/commands/matrix.js +179 -27
  32. package/src/commands/mcpscaf.js +145 -33
  33. package/src/commands/meminj.js +145 -33
  34. package/src/commands/nostr.js +178 -27
  35. package/src/commands/orchestrate.js +217 -0
  36. package/src/commands/orchgov.js +144 -33
  37. package/src/commands/pdfp.js +109 -27
  38. package/src/commands/perf.js +169 -32
  39. package/src/commands/perm.js +144 -33
  40. package/src/commands/pipeline.js +207 -52
  41. package/src/commands/planmode.js +141 -32
  42. package/src/commands/privacy.js +203 -0
  43. package/src/commands/promcomp.js +111 -27
  44. package/src/commands/recommend.js +177 -34
  45. package/src/commands/reputation.js +208 -0
  46. package/src/commands/sandbox.js +206 -0
  47. package/src/commands/seshhook.js +145 -33
  48. package/src/commands/seshsearch.js +141 -33
  49. package/src/commands/seshtail.js +144 -33
  50. package/src/commands/seshu.js +152 -33
  51. package/src/commands/sganal.js +123 -29
  52. package/src/commands/siem.js +201 -34
  53. package/src/commands/sla.js +212 -0
  54. package/src/commands/slotfill.js +146 -33
  55. package/src/commands/social.js +157 -32
  56. package/src/commands/stress.js +206 -0
  57. package/src/commands/svccont.js +145 -33
  58. package/src/commands/terraform.js +206 -0
  59. package/src/commands/tms.js +171 -33
  60. package/src/commands/topiccls.js +146 -33
  61. package/src/commands/uprof.js +141 -32
  62. package/src/commands/vcheck.js +122 -28
  63. package/src/commands/webfetch.js +141 -32
  64. package/src/commands/zkp.js +184 -28
  65. package/src/index.js +40 -0
  66. package/src/lib/a2a-protocol.js +319 -51
  67. package/src/lib/activitypub-bridge.js +288 -50
  68. package/src/lib/agent-economy.js +304 -51
  69. package/src/lib/app-builder.js +279 -46
  70. package/src/lib/audit-logger.js +321 -0
  71. package/src/lib/autonomous-agent.js +284 -48
  72. package/src/lib/bi-engine.js +283 -49
  73. package/src/lib/bm25-search.js +301 -49
  74. package/src/lib/browser-automation.js +296 -49
  75. package/src/lib/chat-core.js +336 -0
  76. package/src/lib/claude-code-bridge.js +341 -0
  77. package/src/lib/compliance-framework-reporter.js +305 -51
  78. package/src/lib/compliance-manager.js +330 -0
  79. package/src/lib/compression-telemetry.js +301 -49
  80. package/src/lib/content-recommender.js +317 -52
  81. package/src/lib/cowork-cron.js +298 -49
  82. package/src/lib/cowork-learning.js +333 -0
  83. package/src/lib/cowork-task-runner.js +308 -51
  84. package/src/lib/cowork-workflow.js +327 -0
  85. package/src/lib/cross-chain.js +311 -51
  86. package/src/lib/dao-governance.js +280 -46
  87. package/src/lib/dlp-engine.js +287 -49
  88. package/src/lib/evolution-system.js +278 -47
  89. package/src/lib/evomap-manager.js +280 -46
  90. package/src/lib/execution-backend.js +294 -48
  91. package/src/lib/feature-flags.js +294 -49
  92. package/src/lib/git-integration.js +285 -47
  93. package/src/lib/hardening-manager.js +341 -0
  94. package/src/lib/hierarchical-memory.js +284 -48
  95. package/src/lib/inference-network.js +308 -51
  96. package/src/lib/iteration-budget.js +302 -50
  97. package/src/lib/knowledge-graph.js +333 -0
  98. package/src/lib/matrix-bridge.js +281 -47
  99. package/src/lib/mcp-scaffold.js +318 -54
  100. package/src/lib/memory-injection.js +288 -49
  101. package/src/lib/nostr-bridge.js +286 -49
  102. package/src/lib/orchestrator.js +293 -48
  103. package/src/lib/pdf-parser.js +298 -49
  104. package/src/lib/perf-tuning.js +309 -50
  105. package/src/lib/permission-engine.js +287 -49
  106. package/src/lib/pipeline-orchestrator.js +289 -49
  107. package/src/lib/plan-mode.js +298 -51
  108. package/src/lib/privacy-computing.js +335 -0
  109. package/src/lib/reputation-optimizer.js +340 -0
  110. package/src/lib/sandbox-v2.js +327 -0
  111. package/src/lib/service-container.js +313 -52
  112. package/src/lib/session-consolidator.js +296 -49
  113. package/src/lib/session-hooks.js +312 -53
  114. package/src/lib/session-search.js +304 -51
  115. package/src/lib/session-tail.js +288 -49
  116. package/src/lib/session-usage.js +298 -52
  117. package/src/lib/siem-exporter.js +298 -51
  118. package/src/lib/skill-marketplace.js +345 -0
  119. package/src/lib/sla-manager.js +341 -0
  120. package/src/lib/slot-filler.js +303 -51
  121. package/src/lib/social-graph-analytics.js +295 -49
  122. package/src/lib/social-graph.js +272 -49
  123. package/src/lib/stress-tester.js +342 -0
  124. package/src/lib/sub-agent-registry.js +302 -53
  125. package/src/lib/task-model-selector.js +302 -50
  126. package/src/lib/terraform-manager.js +333 -0
  127. package/src/lib/todo-manager.js +281 -47
  128. package/src/lib/token-incentive.js +341 -0
  129. package/src/lib/topic-classifier.js +297 -49
  130. package/src/lib/user-profile.js +294 -50
  131. package/src/lib/version-checker.js +304 -50
  132. package/src/lib/web-fetch.js +292 -51
  133. package/src/lib/zkp-engine.js +286 -49
@@ -399,25 +399,62 @@ export function _resetState() {
399
399
  _customLexicons.clear();
400
400
  }
401
401
 
402
-
403
402
  // ===== V2 Surface: Topic Classifier governance overlay (CLI v0.140.0) =====
404
403
  export const TOPIC_CLS_PROFILE_MATURITY_V2 = Object.freeze({
405
- PENDING: "pending", ACTIVE: "active", STALE: "stale", ARCHIVED: "archived",
404
+ PENDING: "pending",
405
+ ACTIVE: "active",
406
+ STALE: "stale",
407
+ ARCHIVED: "archived",
406
408
  });
407
409
  export const TOPIC_CLS_JOB_LIFECYCLE_V2 = Object.freeze({
408
- QUEUED: "queued", RUNNING: "running", COMPLETED: "completed", FAILED: "failed", CANCELLED: "cancelled",
410
+ QUEUED: "queued",
411
+ RUNNING: "running",
412
+ COMPLETED: "completed",
413
+ FAILED: "failed",
414
+ CANCELLED: "cancelled",
409
415
  });
410
416
 
411
417
  const _tcpTrans = new Map([
412
- [TOPIC_CLS_PROFILE_MATURITY_V2.PENDING, new Set([TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE, TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED])],
413
- [TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE, new Set([TOPIC_CLS_PROFILE_MATURITY_V2.STALE, TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED])],
414
- [TOPIC_CLS_PROFILE_MATURITY_V2.STALE, new Set([TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE, TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED])],
418
+ [
419
+ TOPIC_CLS_PROFILE_MATURITY_V2.PENDING,
420
+ new Set([
421
+ TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE,
422
+ TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED,
423
+ ]),
424
+ ],
425
+ [
426
+ TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE,
427
+ new Set([
428
+ TOPIC_CLS_PROFILE_MATURITY_V2.STALE,
429
+ TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED,
430
+ ]),
431
+ ],
432
+ [
433
+ TOPIC_CLS_PROFILE_MATURITY_V2.STALE,
434
+ new Set([
435
+ TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE,
436
+ TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED,
437
+ ]),
438
+ ],
415
439
  [TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
416
440
  ]);
417
441
  const _tcpTerminal = new Set([TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED]);
418
442
  const _tcjTrans = new Map([
419
- [TOPIC_CLS_JOB_LIFECYCLE_V2.QUEUED, new Set([TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING, TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED])],
420
- [TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING, new Set([TOPIC_CLS_JOB_LIFECYCLE_V2.COMPLETED, TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED, TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED])],
443
+ [
444
+ TOPIC_CLS_JOB_LIFECYCLE_V2.QUEUED,
445
+ new Set([
446
+ TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING,
447
+ TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED,
448
+ ]),
449
+ ],
450
+ [
451
+ TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING,
452
+ new Set([
453
+ TOPIC_CLS_JOB_LIFECYCLE_V2.COMPLETED,
454
+ TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED,
455
+ TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED,
456
+ ]),
457
+ ],
421
458
  [TOPIC_CLS_JOB_LIFECYCLE_V2.COMPLETED, new Set()],
422
459
  [TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED, new Set()],
423
460
  [TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED, new Set()],
@@ -430,76 +467,287 @@ let _tcpMaxPendingJobsPerProfile = 20;
430
467
  let _tcpIdleMs = 14 * 24 * 60 * 60 * 1000;
431
468
  let _tcjStuckMs = 5 * 60 * 1000;
432
469
 
433
- function _tcpPos(n, lbl) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${lbl} must be positive integer`); return v; }
470
+ function _tcpPos(n, lbl) {
471
+ const v = Math.floor(Number(n));
472
+ if (!Number.isFinite(v) || v <= 0)
473
+ throw new Error(`${lbl} must be positive integer`);
474
+ return v;
475
+ }
434
476
 
435
- export function setMaxActiveTopicClsProfilesPerOwnerV2(n) { _tcpMaxActivePerOwner = _tcpPos(n, "maxActiveTopicClsProfilesPerOwner"); }
436
- export function getMaxActiveTopicClsProfilesPerOwnerV2() { return _tcpMaxActivePerOwner; }
437
- export function setMaxPendingTopicClsJobsPerProfileV2(n) { _tcpMaxPendingJobsPerProfile = _tcpPos(n, "maxPendingTopicClsJobsPerProfile"); }
438
- export function getMaxPendingTopicClsJobsPerProfileV2() { return _tcpMaxPendingJobsPerProfile; }
439
- export function setTopicClsProfileIdleMsV2(n) { _tcpIdleMs = _tcpPos(n, "topicClsProfileIdleMs"); }
440
- export function getTopicClsProfileIdleMsV2() { return _tcpIdleMs; }
441
- export function setTopicClsJobStuckMsV2(n) { _tcjStuckMs = _tcpPos(n, "topicClsJobStuckMs"); }
442
- export function getTopicClsJobStuckMsV2() { return _tcjStuckMs; }
477
+ export function setMaxActiveTopicClsProfilesPerOwnerV2(n) {
478
+ _tcpMaxActivePerOwner = _tcpPos(n, "maxActiveTopicClsProfilesPerOwner");
479
+ }
480
+ export function getMaxActiveTopicClsProfilesPerOwnerV2() {
481
+ return _tcpMaxActivePerOwner;
482
+ }
483
+ export function setMaxPendingTopicClsJobsPerProfileV2(n) {
484
+ _tcpMaxPendingJobsPerProfile = _tcpPos(n, "maxPendingTopicClsJobsPerProfile");
485
+ }
486
+ export function getMaxPendingTopicClsJobsPerProfileV2() {
487
+ return _tcpMaxPendingJobsPerProfile;
488
+ }
489
+ export function setTopicClsProfileIdleMsV2(n) {
490
+ _tcpIdleMs = _tcpPos(n, "topicClsProfileIdleMs");
491
+ }
492
+ export function getTopicClsProfileIdleMsV2() {
493
+ return _tcpIdleMs;
494
+ }
495
+ export function setTopicClsJobStuckMsV2(n) {
496
+ _tcjStuckMs = _tcpPos(n, "topicClsJobStuckMs");
497
+ }
498
+ export function getTopicClsJobStuckMsV2() {
499
+ return _tcjStuckMs;
500
+ }
443
501
 
444
502
  export function _resetStateTopicClsV2() {
445
- _tcpsV2.clear(); _tcjsV2.clear();
446
- _tcpMaxActivePerOwner = 8; _tcpMaxPendingJobsPerProfile = 20;
447
- _tcpIdleMs = 14 * 24 * 60 * 60 * 1000; _tcjStuckMs = 5 * 60 * 1000;
503
+ _tcpsV2.clear();
504
+ _tcjsV2.clear();
505
+ _tcpMaxActivePerOwner = 8;
506
+ _tcpMaxPendingJobsPerProfile = 20;
507
+ _tcpIdleMs = 14 * 24 * 60 * 60 * 1000;
508
+ _tcjStuckMs = 5 * 60 * 1000;
448
509
  }
449
510
 
450
511
  export function registerTopicClsProfileV2({ id, owner, model, metadata } = {}) {
451
512
  if (!id || typeof id !== "string") throw new Error("id is required");
452
513
  if (!owner || typeof owner !== "string") throw new Error("owner is required");
453
- if (_tcpsV2.has(id)) throw new Error(`topic cls profile ${id} already registered`);
514
+ if (_tcpsV2.has(id))
515
+ throw new Error(`topic cls profile ${id} already registered`);
454
516
  const now = Date.now();
455
- const p = { id, owner, model: model || "default", status: TOPIC_CLS_PROFILE_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, activatedAt: null, archivedAt: null, lastTouchedAt: now, metadata: { ...(metadata || {}) } };
517
+ const p = {
518
+ id,
519
+ owner,
520
+ model: model || "default",
521
+ status: TOPIC_CLS_PROFILE_MATURITY_V2.PENDING,
522
+ createdAt: now,
523
+ updatedAt: now,
524
+ activatedAt: null,
525
+ archivedAt: null,
526
+ lastTouchedAt: now,
527
+ metadata: { ...(metadata || {}) },
528
+ };
456
529
  _tcpsV2.set(id, p);
457
530
  return { ...p, metadata: { ...p.metadata } };
458
531
  }
459
- function _tcpCheckP(from, to) { const a = _tcpTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid topic cls profile transition ${from} → ${to}`); }
460
- function _tcpCountActive(owner) { let n = 0; for (const p of _tcpsV2.values()) if (p.owner === owner && p.status === TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE) n++; return n; }
532
+ function _tcpCheckP(from, to) {
533
+ const a = _tcpTrans.get(from);
534
+ if (!a || !a.has(to))
535
+ throw new Error(`invalid topic cls profile transition ${from} → ${to}`);
536
+ }
537
+ function _tcpCountActive(owner) {
538
+ let n = 0;
539
+ for (const p of _tcpsV2.values())
540
+ if (p.owner === owner && p.status === TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE)
541
+ n++;
542
+ return n;
543
+ }
461
544
 
462
545
  export function activateTopicClsProfileV2(id) {
463
- const p = _tcpsV2.get(id); if (!p) throw new Error(`topic cls profile ${id} not found`);
546
+ const p = _tcpsV2.get(id);
547
+ if (!p) throw new Error(`topic cls profile ${id} not found`);
464
548
  _tcpCheckP(p.status, TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE);
465
549
  const recovery = p.status === TOPIC_CLS_PROFILE_MATURITY_V2.STALE;
466
- if (!recovery) { const c = _tcpCountActive(p.owner); if (c >= _tcpMaxActivePerOwner) throw new Error(`max active topic cls profiles per owner (${_tcpMaxActivePerOwner}) reached for ${p.owner}`); }
467
- const now = Date.now(); p.status = TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE; p.updatedAt = now; p.lastTouchedAt = now; if (!p.activatedAt) p.activatedAt = now;
550
+ if (!recovery) {
551
+ const c = _tcpCountActive(p.owner);
552
+ if (c >= _tcpMaxActivePerOwner)
553
+ throw new Error(
554
+ `max active topic cls profiles per owner (${_tcpMaxActivePerOwner}) reached for ${p.owner}`,
555
+ );
556
+ }
557
+ const now = Date.now();
558
+ p.status = TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE;
559
+ p.updatedAt = now;
560
+ p.lastTouchedAt = now;
561
+ if (!p.activatedAt) p.activatedAt = now;
562
+ return { ...p, metadata: { ...p.metadata } };
563
+ }
564
+ export function staleTopicClsProfileV2(id) {
565
+ const p = _tcpsV2.get(id);
566
+ if (!p) throw new Error(`topic cls profile ${id} not found`);
567
+ _tcpCheckP(p.status, TOPIC_CLS_PROFILE_MATURITY_V2.STALE);
568
+ p.status = TOPIC_CLS_PROFILE_MATURITY_V2.STALE;
569
+ p.updatedAt = Date.now();
570
+ return { ...p, metadata: { ...p.metadata } };
571
+ }
572
+ export function archiveTopicClsProfileV2(id) {
573
+ const p = _tcpsV2.get(id);
574
+ if (!p) throw new Error(`topic cls profile ${id} not found`);
575
+ _tcpCheckP(p.status, TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED);
576
+ const now = Date.now();
577
+ p.status = TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED;
578
+ p.updatedAt = now;
579
+ if (!p.archivedAt) p.archivedAt = now;
580
+ return { ...p, metadata: { ...p.metadata } };
581
+ }
582
+ export function touchTopicClsProfileV2(id) {
583
+ const p = _tcpsV2.get(id);
584
+ if (!p) throw new Error(`topic cls profile ${id} not found`);
585
+ if (_tcpTerminal.has(p.status))
586
+ throw new Error(`cannot touch terminal topic cls profile ${id}`);
587
+ const now = Date.now();
588
+ p.lastTouchedAt = now;
589
+ p.updatedAt = now;
590
+ return { ...p, metadata: { ...p.metadata } };
591
+ }
592
+ export function getTopicClsProfileV2(id) {
593
+ const p = _tcpsV2.get(id);
594
+ if (!p) return null;
468
595
  return { ...p, metadata: { ...p.metadata } };
469
596
  }
470
- export function staleTopicClsProfileV2(id) { const p = _tcpsV2.get(id); if (!p) throw new Error(`topic cls profile ${id} not found`); _tcpCheckP(p.status, TOPIC_CLS_PROFILE_MATURITY_V2.STALE); p.status = TOPIC_CLS_PROFILE_MATURITY_V2.STALE; p.updatedAt = Date.now(); return { ...p, metadata: { ...p.metadata } }; }
471
- export function archiveTopicClsProfileV2(id) { const p = _tcpsV2.get(id); if (!p) throw new Error(`topic cls profile ${id} not found`); _tcpCheckP(p.status, TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED); const now = Date.now(); p.status = TOPIC_CLS_PROFILE_MATURITY_V2.ARCHIVED; p.updatedAt = now; if (!p.archivedAt) p.archivedAt = now; return { ...p, metadata: { ...p.metadata } }; }
472
- export function touchTopicClsProfileV2(id) { const p = _tcpsV2.get(id); if (!p) throw new Error(`topic cls profile ${id} not found`); if (_tcpTerminal.has(p.status)) throw new Error(`cannot touch terminal topic cls profile ${id}`); const now = Date.now(); p.lastTouchedAt = now; p.updatedAt = now; return { ...p, metadata: { ...p.metadata } }; }
473
- export function getTopicClsProfileV2(id) { const p = _tcpsV2.get(id); if (!p) return null; return { ...p, metadata: { ...p.metadata } }; }
474
- export function listTopicClsProfilesV2() { return [..._tcpsV2.values()].map((p) => ({ ...p, metadata: { ...p.metadata } })); }
597
+ export function listTopicClsProfilesV2() {
598
+ return [..._tcpsV2.values()].map((p) => ({
599
+ ...p,
600
+ metadata: { ...p.metadata },
601
+ }));
602
+ }
475
603
 
476
- function _tcjCountPending(profileId) { let n = 0; for (const j of _tcjsV2.values()) if (j.profileId === profileId && (j.status === TOPIC_CLS_JOB_LIFECYCLE_V2.QUEUED || j.status === TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING)) n++; return n; }
604
+ function _tcjCountPending(profileId) {
605
+ let n = 0;
606
+ for (const j of _tcjsV2.values())
607
+ if (
608
+ j.profileId === profileId &&
609
+ (j.status === TOPIC_CLS_JOB_LIFECYCLE_V2.QUEUED ||
610
+ j.status === TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING)
611
+ )
612
+ n++;
613
+ return n;
614
+ }
477
615
 
478
616
  export function createTopicClsJobV2({ id, profileId, text, metadata } = {}) {
479
617
  if (!id || typeof id !== "string") throw new Error("id is required");
480
- if (!profileId || typeof profileId !== "string") throw new Error("profileId is required");
618
+ if (!profileId || typeof profileId !== "string")
619
+ throw new Error("profileId is required");
481
620
  if (_tcjsV2.has(id)) throw new Error(`topic cls job ${id} already exists`);
482
- if (!_tcpsV2.has(profileId)) throw new Error(`topic cls profile ${profileId} not found`);
621
+ if (!_tcpsV2.has(profileId))
622
+ throw new Error(`topic cls profile ${profileId} not found`);
483
623
  const pending = _tcjCountPending(profileId);
484
- if (pending >= _tcpMaxPendingJobsPerProfile) throw new Error(`max pending topic cls jobs per profile (${_tcpMaxPendingJobsPerProfile}) reached for ${profileId}`);
624
+ if (pending >= _tcpMaxPendingJobsPerProfile)
625
+ throw new Error(
626
+ `max pending topic cls jobs per profile (${_tcpMaxPendingJobsPerProfile}) reached for ${profileId}`,
627
+ );
485
628
  const now = Date.now();
486
- const j = { id, profileId, text: text || "", status: TOPIC_CLS_JOB_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
629
+ const j = {
630
+ id,
631
+ profileId,
632
+ text: text || "",
633
+ status: TOPIC_CLS_JOB_LIFECYCLE_V2.QUEUED,
634
+ createdAt: now,
635
+ updatedAt: now,
636
+ startedAt: null,
637
+ settledAt: null,
638
+ metadata: { ...(metadata || {}) },
639
+ };
487
640
  _tcjsV2.set(id, j);
488
641
  return { ...j, metadata: { ...j.metadata } };
489
642
  }
490
- function _tcjCheckJ(from, to) { const a = _tcjTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid topic cls job transition ${from} → ${to}`); }
491
- export function startTopicClsJobV2(id) { const j = _tcjsV2.get(id); if (!j) throw new Error(`topic cls job ${id} not found`); _tcjCheckJ(j.status, TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING); const now = Date.now(); j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING; j.updatedAt = now; if (!j.startedAt) j.startedAt = now; return { ...j, metadata: { ...j.metadata } }; }
492
- export function completeTopicClsJobV2(id) { const j = _tcjsV2.get(id); if (!j) throw new Error(`topic cls job ${id} not found`); _tcjCheckJ(j.status, TOPIC_CLS_JOB_LIFECYCLE_V2.COMPLETED); const now = Date.now(); j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.COMPLETED; j.updatedAt = now; if (!j.settledAt) j.settledAt = now; return { ...j, metadata: { ...j.metadata } }; }
493
- export function failTopicClsJobV2(id, reason) { const j = _tcjsV2.get(id); if (!j) throw new Error(`topic cls job ${id} not found`); _tcjCheckJ(j.status, TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED); const now = Date.now(); j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED; j.updatedAt = now; if (!j.settledAt) j.settledAt = now; if (reason) j.metadata.failReason = String(reason); return { ...j, metadata: { ...j.metadata } }; }
494
- export function cancelTopicClsJobV2(id, reason) { const j = _tcjsV2.get(id); if (!j) throw new Error(`topic cls job ${id} not found`); _tcjCheckJ(j.status, TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED); const now = Date.now(); j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED; j.updatedAt = now; if (!j.settledAt) j.settledAt = now; if (reason) j.metadata.cancelReason = String(reason); return { ...j, metadata: { ...j.metadata } }; }
495
- export function getTopicClsJobV2(id) { const j = _tcjsV2.get(id); if (!j) return null; return { ...j, metadata: { ...j.metadata } }; }
496
- export function listTopicClsJobsV2() { return [..._tcjsV2.values()].map((j) => ({ ...j, metadata: { ...j.metadata } })); }
643
+ function _tcjCheckJ(from, to) {
644
+ const a = _tcjTrans.get(from);
645
+ if (!a || !a.has(to))
646
+ throw new Error(`invalid topic cls job transition ${from} ${to}`);
647
+ }
648
+ export function startTopicClsJobV2(id) {
649
+ const j = _tcjsV2.get(id);
650
+ if (!j) throw new Error(`topic cls job ${id} not found`);
651
+ _tcjCheckJ(j.status, TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING);
652
+ const now = Date.now();
653
+ j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING;
654
+ j.updatedAt = now;
655
+ if (!j.startedAt) j.startedAt = now;
656
+ return { ...j, metadata: { ...j.metadata } };
657
+ }
658
+ export function completeTopicClsJobV2(id) {
659
+ const j = _tcjsV2.get(id);
660
+ if (!j) throw new Error(`topic cls job ${id} not found`);
661
+ _tcjCheckJ(j.status, TOPIC_CLS_JOB_LIFECYCLE_V2.COMPLETED);
662
+ const now = Date.now();
663
+ j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.COMPLETED;
664
+ j.updatedAt = now;
665
+ if (!j.settledAt) j.settledAt = now;
666
+ return { ...j, metadata: { ...j.metadata } };
667
+ }
668
+ export function failTopicClsJobV2(id, reason) {
669
+ const j = _tcjsV2.get(id);
670
+ if (!j) throw new Error(`topic cls job ${id} not found`);
671
+ _tcjCheckJ(j.status, TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED);
672
+ const now = Date.now();
673
+ j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED;
674
+ j.updatedAt = now;
675
+ if (!j.settledAt) j.settledAt = now;
676
+ if (reason) j.metadata.failReason = String(reason);
677
+ return { ...j, metadata: { ...j.metadata } };
678
+ }
679
+ export function cancelTopicClsJobV2(id, reason) {
680
+ const j = _tcjsV2.get(id);
681
+ if (!j) throw new Error(`topic cls job ${id} not found`);
682
+ _tcjCheckJ(j.status, TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED);
683
+ const now = Date.now();
684
+ j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.CANCELLED;
685
+ j.updatedAt = now;
686
+ if (!j.settledAt) j.settledAt = now;
687
+ if (reason) j.metadata.cancelReason = String(reason);
688
+ return { ...j, metadata: { ...j.metadata } };
689
+ }
690
+ export function getTopicClsJobV2(id) {
691
+ const j = _tcjsV2.get(id);
692
+ if (!j) return null;
693
+ return { ...j, metadata: { ...j.metadata } };
694
+ }
695
+ export function listTopicClsJobsV2() {
696
+ return [..._tcjsV2.values()].map((j) => ({
697
+ ...j,
698
+ metadata: { ...j.metadata },
699
+ }));
700
+ }
497
701
 
498
- export function autoStaleIdleTopicClsProfilesV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const p of _tcpsV2.values()) if (p.status === TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE && (t - p.lastTouchedAt) >= _tcpIdleMs) { p.status = TOPIC_CLS_PROFILE_MATURITY_V2.STALE; p.updatedAt = t; flipped.push(p.id); } return { flipped, count: flipped.length }; }
499
- export function autoFailStuckTopicClsJobsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const j of _tcjsV2.values()) if (j.status === TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING && j.startedAt != null && (t - j.startedAt) >= _tcjStuckMs) { j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED; j.updatedAt = t; if (!j.settledAt) j.settledAt = t; j.metadata.failReason = "auto-fail-stuck"; flipped.push(j.id); } return { flipped, count: flipped.length }; }
702
+ export function autoStaleIdleTopicClsProfilesV2({ now } = {}) {
703
+ const t = now ?? Date.now();
704
+ const flipped = [];
705
+ for (const p of _tcpsV2.values())
706
+ if (
707
+ p.status === TOPIC_CLS_PROFILE_MATURITY_V2.ACTIVE &&
708
+ t - p.lastTouchedAt >= _tcpIdleMs
709
+ ) {
710
+ p.status = TOPIC_CLS_PROFILE_MATURITY_V2.STALE;
711
+ p.updatedAt = t;
712
+ flipped.push(p.id);
713
+ }
714
+ return { flipped, count: flipped.length };
715
+ }
716
+ export function autoFailStuckTopicClsJobsV2({ now } = {}) {
717
+ const t = now ?? Date.now();
718
+ const flipped = [];
719
+ for (const j of _tcjsV2.values())
720
+ if (
721
+ j.status === TOPIC_CLS_JOB_LIFECYCLE_V2.RUNNING &&
722
+ j.startedAt != null &&
723
+ t - j.startedAt >= _tcjStuckMs
724
+ ) {
725
+ j.status = TOPIC_CLS_JOB_LIFECYCLE_V2.FAILED;
726
+ j.updatedAt = t;
727
+ if (!j.settledAt) j.settledAt = t;
728
+ j.metadata.failReason = "auto-fail-stuck";
729
+ flipped.push(j.id);
730
+ }
731
+ return { flipped, count: flipped.length };
732
+ }
500
733
 
501
734
  export function getTopicClassifierGovStatsV2() {
502
- const profilesByStatus = {}; for (const s of Object.values(TOPIC_CLS_PROFILE_MATURITY_V2)) profilesByStatus[s] = 0; for (const p of _tcpsV2.values()) profilesByStatus[p.status]++;
503
- const jobsByStatus = {}; for (const s of Object.values(TOPIC_CLS_JOB_LIFECYCLE_V2)) jobsByStatus[s] = 0; for (const j of _tcjsV2.values()) jobsByStatus[j.status]++;
504
- return { totalTopicClsProfilesV2: _tcpsV2.size, totalTopicClsJobsV2: _tcjsV2.size, maxActiveTopicClsProfilesPerOwner: _tcpMaxActivePerOwner, maxPendingTopicClsJobsPerProfile: _tcpMaxPendingJobsPerProfile, topicClsProfileIdleMs: _tcpIdleMs, topicClsJobStuckMs: _tcjStuckMs, profilesByStatus, jobsByStatus };
735
+ const profilesByStatus = {};
736
+ for (const s of Object.values(TOPIC_CLS_PROFILE_MATURITY_V2))
737
+ profilesByStatus[s] = 0;
738
+ for (const p of _tcpsV2.values()) profilesByStatus[p.status]++;
739
+ const jobsByStatus = {};
740
+ for (const s of Object.values(TOPIC_CLS_JOB_LIFECYCLE_V2))
741
+ jobsByStatus[s] = 0;
742
+ for (const j of _tcjsV2.values()) jobsByStatus[j.status]++;
743
+ return {
744
+ totalTopicClsProfilesV2: _tcpsV2.size,
745
+ totalTopicClsJobsV2: _tcjsV2.size,
746
+ maxActiveTopicClsProfilesPerOwner: _tcpMaxActivePerOwner,
747
+ maxPendingTopicClsJobsPerProfile: _tcpMaxPendingJobsPerProfile,
748
+ topicClsProfileIdleMs: _tcpIdleMs,
749
+ topicClsJobStuckMs: _tcjStuckMs,
750
+ profilesByStatus,
751
+ jobsByStatus,
752
+ };
505
753
  }