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.
- package/package.json +1 -1
- package/src/commands/a2a.js +196 -28
- package/src/commands/activitypub.js +364 -27
- package/src/commands/agent-network.js +217 -0
- package/src/commands/agent.js +587 -103
- package/src/commands/audit.js +206 -0
- package/src/commands/automation.js +201 -0
- package/src/commands/bi.js +355 -27
- package/src/commands/bm25.js +111 -27
- package/src/commands/browse.js +403 -29
- package/src/commands/ccron.js +128 -28
- package/src/commands/chat.js +207 -0
- package/src/commands/codegen.js +207 -0
- package/src/commands/collab.js +211 -0
- package/src/commands/compliance.js +824 -34
- package/src/commands/compt.js +127 -29
- package/src/commands/consol.js +8 -2
- package/src/commands/cowork.js +783 -34
- package/src/commands/crosschain.js +182 -28
- package/src/commands/dao.js +182 -28
- package/src/commands/dbevo.js +227 -0
- package/src/commands/dev.js +207 -0
- package/src/commands/did-v2.js +217 -0
- package/src/commands/did.js +221 -0
- package/src/commands/dlp.js +385 -27
- package/src/commands/economy.js +205 -50
- package/src/commands/evolution.js +203 -50
- package/src/commands/evomap.js +387 -27
- package/src/commands/export.js +213 -0
- package/src/commands/federation.js +209 -0
- package/src/commands/fflag.js +74 -22
- package/src/commands/fusion.js +205 -0
- package/src/commands/git.js +177 -37
- package/src/commands/governance.js +209 -0
- package/src/commands/hardening.js +209 -0
- package/src/commands/hmemory.js +204 -50
- package/src/commands/hook.js +209 -0
- package/src/commands/import.js +209 -0
- package/src/commands/incentive.js +209 -0
- package/src/commands/inference.js +170 -34
- package/src/commands/infra.js +203 -0
- package/src/commands/instinct.js +209 -0
- package/src/commands/ipfs.js +207 -0
- package/src/commands/itbudget.js +149 -33
- package/src/commands/kg.js +206 -0
- package/src/commands/llm.js +217 -0
- package/src/commands/lowcode.js +195 -38
- package/src/commands/marketplace.js +206 -0
- package/src/commands/matrix.js +386 -27
- package/src/commands/mcp.js +217 -0
- package/src/commands/mcpscaf.js +145 -33
- package/src/commands/meminj.js +145 -33
- package/src/commands/memory.js +209 -0
- package/src/commands/multimodal.js +203 -0
- package/src/commands/nlprog.js +225 -0
- package/src/commands/nostr.js +387 -27
- package/src/commands/note.js +205 -0
- package/src/commands/ops.js +219 -0
- package/src/commands/orchestrate.js +217 -0
- package/src/commands/orchgov.js +144 -33
- package/src/commands/org.js +209 -0
- package/src/commands/p2p.js +209 -0
- package/src/commands/pdfp.js +109 -27
- package/src/commands/perception.js +209 -0
- package/src/commands/perf.js +169 -32
- package/src/commands/perm.js +144 -33
- package/src/commands/permmem.js +203 -0
- package/src/commands/pipeline.js +207 -52
- package/src/commands/planmode.js +141 -32
- package/src/commands/plugin-ecosystem.js +209 -0
- package/src/commands/pqc.js +213 -0
- package/src/commands/privacy.js +203 -0
- package/src/commands/promcomp.js +111 -27
- package/src/commands/quantization.js +207 -0
- package/src/commands/rcache.js +205 -0
- package/src/commands/recommend.js +410 -34
- package/src/commands/reputation.js +208 -0
- package/src/commands/runtime.js +205 -0
- package/src/commands/sandbox.js +206 -0
- package/src/commands/scim.js +209 -0
- package/src/commands/seshhook.js +145 -33
- package/src/commands/seshsearch.js +141 -33
- package/src/commands/seshtail.js +144 -33
- package/src/commands/seshu.js +152 -33
- package/src/commands/session.js +209 -0
- package/src/commands/sganal.js +123 -29
- package/src/commands/siem.js +201 -34
- package/src/commands/skill.js +207 -0
- package/src/commands/sla.js +212 -0
- package/src/commands/slotfill.js +146 -33
- package/src/commands/social.js +358 -32
- package/src/commands/sso.js +209 -0
- package/src/commands/stress.js +206 -0
- package/src/commands/svccont.js +145 -33
- package/src/commands/sync.js +209 -0
- package/src/commands/tech.js +209 -0
- package/src/commands/tenant.js +217 -0
- package/src/commands/terraform.js +206 -0
- package/src/commands/tms.js +171 -33
- package/src/commands/tokens.js +209 -0
- package/src/commands/topiccls.js +146 -33
- package/src/commands/trust.js +217 -0
- package/src/commands/uprof.js +141 -32
- package/src/commands/vcheck.js +122 -28
- package/src/commands/wallet.js +209 -0
- package/src/commands/webfetch.js +141 -32
- package/src/commands/workflow.js +203 -0
- package/src/commands/zkp.js +184 -28
- package/src/index.js +180 -0
- package/src/lib/a2a-protocol.js +319 -51
- package/src/lib/activitypub-bridge.js +622 -50
- package/src/lib/agent-economy.js +304 -51
- package/src/lib/agent-network.js +341 -0
- package/src/lib/aiops.js +346 -0
- package/src/lib/app-builder.js +279 -46
- package/src/lib/audit-logger.js +321 -0
- package/src/lib/automation-engine.js +335 -0
- package/src/lib/autonomous-agent.js +284 -48
- package/src/lib/autonomous-developer.js +332 -0
- package/src/lib/bi-engine.js +616 -49
- package/src/lib/bm25-search.js +301 -49
- package/src/lib/browser-automation.js +630 -49
- package/src/lib/chat-core.js +336 -0
- package/src/lib/claude-code-bridge.js +341 -0
- package/src/lib/code-agent.js +339 -0
- package/src/lib/collaboration-governance.js +334 -0
- package/src/lib/community-governance.js +346 -0
- package/src/lib/compliance-framework-reporter.js +305 -51
- package/src/lib/compliance-manager.js +330 -0
- package/src/lib/compression-telemetry.js +301 -49
- package/src/lib/content-recommendation.js +351 -0
- package/src/lib/content-recommender.js +317 -52
- package/src/lib/cowork-cron.js +298 -49
- package/src/lib/cowork-learning.js +333 -0
- package/src/lib/cowork-share.js +338 -0
- package/src/lib/cowork-task-runner.js +308 -51
- package/src/lib/cowork-workflow.js +327 -0
- package/src/lib/cross-chain.js +311 -51
- package/src/lib/dao-governance.js +280 -46
- package/src/lib/dbevo.js +351 -0
- package/src/lib/decentral-infra.js +330 -0
- package/src/lib/did-manager.js +341 -0
- package/src/lib/did-v2-manager.js +341 -0
- package/src/lib/dlp-engine.js +626 -49
- package/src/lib/evolution-system.js +278 -47
- package/src/lib/evomap-governance.js +334 -0
- package/src/lib/evomap-manager.js +280 -46
- package/src/lib/execution-backend.js +294 -48
- package/src/lib/feature-flags.js +294 -49
- package/src/lib/federation-hardening.js +340 -0
- package/src/lib/git-integration.js +285 -47
- package/src/lib/hardening-manager.js +341 -0
- package/src/lib/hierarchical-memory.js +284 -48
- package/src/lib/hook-manager.js +341 -0
- package/src/lib/inference-network.js +308 -51
- package/src/lib/instinct-manager.js +346 -0
- package/src/lib/ipfs-storage.js +334 -0
- package/src/lib/iteration-budget.js +302 -50
- package/src/lib/knowledge-exporter.js +341 -0
- package/src/lib/knowledge-graph.js +333 -0
- package/src/lib/knowledge-importer.js +341 -0
- package/src/lib/llm-providers.js +346 -0
- package/src/lib/matrix-bridge.js +620 -47
- package/src/lib/mcp-registry.js +346 -0
- package/src/lib/mcp-scaffold.js +318 -54
- package/src/lib/memory-injection.js +288 -49
- package/src/lib/memory-manager.js +336 -0
- package/src/lib/multimodal.js +330 -0
- package/src/lib/nl-programming.js +341 -0
- package/src/lib/nostr-bridge.js +622 -49
- package/src/lib/note-versioning.js +339 -0
- package/src/lib/orchestrator.js +293 -48
- package/src/lib/org-manager.js +336 -0
- package/src/lib/p2p-manager.js +341 -0
- package/src/lib/pdf-parser.js +298 -49
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +309 -50
- package/src/lib/permanent-memory.js +327 -0
- package/src/lib/permission-engine.js +287 -49
- package/src/lib/pipeline-orchestrator.js +289 -49
- package/src/lib/plan-mode.js +298 -51
- package/src/lib/plugin-ecosystem.js +346 -0
- package/src/lib/pqc-manager.js +346 -0
- package/src/lib/privacy-computing.js +335 -0
- package/src/lib/protocol-fusion.js +338 -0
- package/src/lib/quantization.js +337 -0
- package/src/lib/reputation-optimizer.js +340 -0
- package/src/lib/response-cache.js +333 -0
- package/src/lib/sandbox-v2.js +327 -0
- package/src/lib/scim-manager.js +346 -0
- package/src/lib/service-container.js +313 -52
- package/src/lib/session-consolidator.js +296 -49
- package/src/lib/session-hooks.js +312 -53
- package/src/lib/session-manager.js +334 -0
- package/src/lib/session-search.js +304 -51
- package/src/lib/session-tail.js +288 -49
- package/src/lib/session-usage.js +298 -52
- package/src/lib/siem-exporter.js +298 -51
- package/src/lib/skill-loader.js +334 -0
- package/src/lib/skill-marketplace.js +345 -0
- package/src/lib/sla-manager.js +341 -0
- package/src/lib/slot-filler.js +303 -51
- package/src/lib/social-graph-analytics.js +295 -49
- package/src/lib/social-graph.js +272 -49
- package/src/lib/social-manager.js +330 -0
- package/src/lib/sso-manager.js +340 -0
- package/src/lib/stress-tester.js +342 -0
- package/src/lib/sub-agent-registry.js +302 -53
- package/src/lib/sync-manager.js +336 -0
- package/src/lib/task-model-selector.js +302 -50
- package/src/lib/tech-learning-engine.js +341 -0
- package/src/lib/tenant-saas.js +341 -0
- package/src/lib/terraform-manager.js +333 -0
- package/src/lib/threat-intel.js +330 -0
- package/src/lib/todo-manager.js +281 -47
- package/src/lib/token-incentive.js +341 -0
- package/src/lib/token-tracker.js +336 -0
- package/src/lib/topic-classifier.js +297 -49
- package/src/lib/trust-security.js +343 -0
- package/src/lib/ueba.js +340 -0
- package/src/lib/universal-runtime.js +330 -0
- package/src/lib/user-profile.js +294 -50
- package/src/lib/version-checker.js +304 -50
- package/src/lib/wallet-manager.js +336 -0
- package/src/lib/web-fetch.js +292 -51
- package/src/lib/workflow-engine.js +330 -0
- package/src/lib/zkp-engine.js +286 -49
package/src/lib/social-graph.js
CHANGED
|
@@ -409,81 +409,304 @@ export function _resetState() {
|
|
|
409
409
|
|
|
410
410
|
// ===== V2 Surface: Social Graph governance overlay (CLI v0.141.0) =====
|
|
411
411
|
export const SG_NODE_MATURITY_V2 = Object.freeze({
|
|
412
|
-
PENDING: "pending",
|
|
412
|
+
PENDING: "pending",
|
|
413
|
+
ACTIVE: "active",
|
|
414
|
+
INACTIVE: "inactive",
|
|
415
|
+
REMOVED: "removed",
|
|
413
416
|
});
|
|
414
417
|
export const SG_EDGE_LIFECYCLE_V2 = Object.freeze({
|
|
415
|
-
PROPOSED: "proposed",
|
|
418
|
+
PROPOSED: "proposed",
|
|
419
|
+
ESTABLISHED: "established",
|
|
420
|
+
SEVERED: "severed",
|
|
421
|
+
EXPIRED: "expired",
|
|
422
|
+
CANCELLED: "cancelled",
|
|
416
423
|
});
|
|
417
424
|
const _sgNTrans = new Map([
|
|
418
|
-
[
|
|
419
|
-
|
|
420
|
-
|
|
425
|
+
[
|
|
426
|
+
SG_NODE_MATURITY_V2.PENDING,
|
|
427
|
+
new Set([SG_NODE_MATURITY_V2.ACTIVE, SG_NODE_MATURITY_V2.REMOVED]),
|
|
428
|
+
],
|
|
429
|
+
[
|
|
430
|
+
SG_NODE_MATURITY_V2.ACTIVE,
|
|
431
|
+
new Set([SG_NODE_MATURITY_V2.INACTIVE, SG_NODE_MATURITY_V2.REMOVED]),
|
|
432
|
+
],
|
|
433
|
+
[
|
|
434
|
+
SG_NODE_MATURITY_V2.INACTIVE,
|
|
435
|
+
new Set([SG_NODE_MATURITY_V2.ACTIVE, SG_NODE_MATURITY_V2.REMOVED]),
|
|
436
|
+
],
|
|
421
437
|
[SG_NODE_MATURITY_V2.REMOVED, new Set()],
|
|
422
438
|
]);
|
|
423
439
|
const _sgNTerminal = new Set([SG_NODE_MATURITY_V2.REMOVED]);
|
|
424
440
|
const _sgETrans = new Map([
|
|
425
|
-
[
|
|
426
|
-
|
|
441
|
+
[
|
|
442
|
+
SG_EDGE_LIFECYCLE_V2.PROPOSED,
|
|
443
|
+
new Set([SG_EDGE_LIFECYCLE_V2.ESTABLISHED, SG_EDGE_LIFECYCLE_V2.CANCELLED]),
|
|
444
|
+
],
|
|
445
|
+
[
|
|
446
|
+
SG_EDGE_LIFECYCLE_V2.ESTABLISHED,
|
|
447
|
+
new Set([SG_EDGE_LIFECYCLE_V2.SEVERED, SG_EDGE_LIFECYCLE_V2.EXPIRED]),
|
|
448
|
+
],
|
|
427
449
|
[SG_EDGE_LIFECYCLE_V2.SEVERED, new Set()],
|
|
428
450
|
[SG_EDGE_LIFECYCLE_V2.EXPIRED, new Set()],
|
|
429
451
|
[SG_EDGE_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
430
452
|
]);
|
|
431
453
|
const _sgNsV2 = new Map();
|
|
432
454
|
const _sgEsV2 = new Map();
|
|
433
|
-
let _sgMaxActivePerOwner = 50,
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
455
|
+
let _sgMaxActivePerOwner = 50,
|
|
456
|
+
_sgMaxPendingEdgesPerNode = 100,
|
|
457
|
+
_sgIdleMs = 60 * 24 * 60 * 60 * 1000,
|
|
458
|
+
_sgStuckMs = 14 * 24 * 60 * 60 * 1000;
|
|
459
|
+
function _sgPos(n, label) {
|
|
460
|
+
const v = Math.floor(Number(n));
|
|
461
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
462
|
+
throw new Error(`${label} must be positive integer`);
|
|
463
|
+
return v;
|
|
464
|
+
}
|
|
465
|
+
function _sgCheckN(from, to) {
|
|
466
|
+
const a = _sgNTrans.get(from);
|
|
467
|
+
if (!a || !a.has(to))
|
|
468
|
+
throw new Error(`invalid sg node transition ${from} → ${to}`);
|
|
469
|
+
}
|
|
470
|
+
function _sgCheckE(from, to) {
|
|
471
|
+
const a = _sgETrans.get(from);
|
|
472
|
+
if (!a || !a.has(to))
|
|
473
|
+
throw new Error(`invalid sg edge transition ${from} → ${to}`);
|
|
474
|
+
}
|
|
475
|
+
export function setMaxActiveSgNodesPerOwnerV2(n) {
|
|
476
|
+
_sgMaxActivePerOwner = _sgPos(n, "maxActiveSgNodesPerOwner");
|
|
477
|
+
}
|
|
478
|
+
export function getMaxActiveSgNodesPerOwnerV2() {
|
|
479
|
+
return _sgMaxActivePerOwner;
|
|
480
|
+
}
|
|
481
|
+
export function setMaxPendingSgEdgesPerNodeV2(n) {
|
|
482
|
+
_sgMaxPendingEdgesPerNode = _sgPos(n, "maxPendingSgEdgesPerNode");
|
|
483
|
+
}
|
|
484
|
+
export function getMaxPendingSgEdgesPerNodeV2() {
|
|
485
|
+
return _sgMaxPendingEdgesPerNode;
|
|
486
|
+
}
|
|
487
|
+
export function setSgNodeIdleMsV2(n) {
|
|
488
|
+
_sgIdleMs = _sgPos(n, "sgNodeIdleMs");
|
|
489
|
+
}
|
|
490
|
+
export function getSgNodeIdleMsV2() {
|
|
491
|
+
return _sgIdleMs;
|
|
492
|
+
}
|
|
493
|
+
export function setSgEdgeStuckMsV2(n) {
|
|
494
|
+
_sgStuckMs = _sgPos(n, "sgEdgeStuckMs");
|
|
495
|
+
}
|
|
496
|
+
export function getSgEdgeStuckMsV2() {
|
|
497
|
+
return _sgStuckMs;
|
|
498
|
+
}
|
|
499
|
+
export function _resetStateSocialGraphV2() {
|
|
500
|
+
_sgNsV2.clear();
|
|
501
|
+
_sgEsV2.clear();
|
|
502
|
+
_sgMaxActivePerOwner = 50;
|
|
503
|
+
_sgMaxPendingEdgesPerNode = 100;
|
|
504
|
+
_sgIdleMs = 60 * 24 * 60 * 60 * 1000;
|
|
505
|
+
_sgStuckMs = 14 * 24 * 60 * 60 * 1000;
|
|
506
|
+
}
|
|
446
507
|
export function registerSgNodeV2({ id, owner, handle, metadata } = {}) {
|
|
447
|
-
if (!id) throw new Error("sg node id required");
|
|
508
|
+
if (!id) throw new Error("sg node id required");
|
|
509
|
+
if (!owner) throw new Error("sg node owner required");
|
|
448
510
|
if (_sgNsV2.has(id)) throw new Error(`sg node ${id} already registered`);
|
|
449
511
|
const now = Date.now();
|
|
450
|
-
const n = {
|
|
451
|
-
|
|
512
|
+
const n = {
|
|
513
|
+
id,
|
|
514
|
+
owner,
|
|
515
|
+
handle: handle || id,
|
|
516
|
+
status: SG_NODE_MATURITY_V2.PENDING,
|
|
517
|
+
createdAt: now,
|
|
518
|
+
updatedAt: now,
|
|
519
|
+
activatedAt: null,
|
|
520
|
+
removedAt: null,
|
|
521
|
+
lastTouchedAt: now,
|
|
522
|
+
metadata: { ...(metadata || {}) },
|
|
523
|
+
};
|
|
524
|
+
_sgNsV2.set(id, n);
|
|
525
|
+
return { ...n, metadata: { ...n.metadata } };
|
|
526
|
+
}
|
|
527
|
+
function _sgCountActive(owner) {
|
|
528
|
+
let n = 0;
|
|
529
|
+
for (const v of _sgNsV2.values())
|
|
530
|
+
if (v.owner === owner && v.status === SG_NODE_MATURITY_V2.ACTIVE) n++;
|
|
531
|
+
return n;
|
|
452
532
|
}
|
|
453
|
-
function _sgCountActive(owner) { let n = 0; for (const v of _sgNsV2.values()) if (v.owner === owner && v.status === SG_NODE_MATURITY_V2.ACTIVE) n++; return n; }
|
|
454
533
|
export function activateSgNodeV2(id) {
|
|
455
|
-
const n = _sgNsV2.get(id);
|
|
534
|
+
const n = _sgNsV2.get(id);
|
|
535
|
+
if (!n) throw new Error(`sg node ${id} not found`);
|
|
456
536
|
_sgCheckN(n.status, SG_NODE_MATURITY_V2.ACTIVE);
|
|
457
537
|
const recovery = n.status === SG_NODE_MATURITY_V2.INACTIVE;
|
|
458
|
-
if (!recovery && _sgCountActive(n.owner) >= _sgMaxActivePerOwner)
|
|
459
|
-
|
|
538
|
+
if (!recovery && _sgCountActive(n.owner) >= _sgMaxActivePerOwner)
|
|
539
|
+
throw new Error(`max active sg nodes for owner ${n.owner} reached`);
|
|
540
|
+
const now = Date.now();
|
|
541
|
+
n.status = SG_NODE_MATURITY_V2.ACTIVE;
|
|
542
|
+
n.updatedAt = now;
|
|
543
|
+
n.lastTouchedAt = now;
|
|
544
|
+
if (!n.activatedAt) n.activatedAt = now;
|
|
545
|
+
return { ...n, metadata: { ...n.metadata } };
|
|
546
|
+
}
|
|
547
|
+
export function deactivateSgNodeV2(id) {
|
|
548
|
+
const n = _sgNsV2.get(id);
|
|
549
|
+
if (!n) throw new Error(`sg node ${id} not found`);
|
|
550
|
+
_sgCheckN(n.status, SG_NODE_MATURITY_V2.INACTIVE);
|
|
551
|
+
n.status = SG_NODE_MATURITY_V2.INACTIVE;
|
|
552
|
+
n.updatedAt = Date.now();
|
|
553
|
+
return { ...n, metadata: { ...n.metadata } };
|
|
554
|
+
}
|
|
555
|
+
export function removeSgNodeV2(id) {
|
|
556
|
+
const n = _sgNsV2.get(id);
|
|
557
|
+
if (!n) throw new Error(`sg node ${id} not found`);
|
|
558
|
+
_sgCheckN(n.status, SG_NODE_MATURITY_V2.REMOVED);
|
|
559
|
+
const now = Date.now();
|
|
560
|
+
n.status = SG_NODE_MATURITY_V2.REMOVED;
|
|
561
|
+
n.updatedAt = now;
|
|
562
|
+
if (!n.removedAt) n.removedAt = now;
|
|
563
|
+
return { ...n, metadata: { ...n.metadata } };
|
|
564
|
+
}
|
|
565
|
+
export function touchSgNodeV2(id) {
|
|
566
|
+
const n = _sgNsV2.get(id);
|
|
567
|
+
if (!n) throw new Error(`sg node ${id} not found`);
|
|
568
|
+
if (_sgNTerminal.has(n.status))
|
|
569
|
+
throw new Error(`cannot touch terminal sg node ${id}`);
|
|
570
|
+
const now = Date.now();
|
|
571
|
+
n.lastTouchedAt = now;
|
|
572
|
+
n.updatedAt = now;
|
|
573
|
+
return { ...n, metadata: { ...n.metadata } };
|
|
574
|
+
}
|
|
575
|
+
export function getSgNodeV2(id) {
|
|
576
|
+
const n = _sgNsV2.get(id);
|
|
577
|
+
if (!n) return null;
|
|
460
578
|
return { ...n, metadata: { ...n.metadata } };
|
|
461
579
|
}
|
|
462
|
-
export function
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
580
|
+
export function listSgNodesV2() {
|
|
581
|
+
return [..._sgNsV2.values()].map((n) => ({
|
|
582
|
+
...n,
|
|
583
|
+
metadata: { ...n.metadata },
|
|
584
|
+
}));
|
|
585
|
+
}
|
|
586
|
+
function _sgCountPending(nodeId) {
|
|
587
|
+
let n = 0;
|
|
588
|
+
for (const e of _sgEsV2.values())
|
|
589
|
+
if (e.nodeId === nodeId && e.status === SG_EDGE_LIFECYCLE_V2.PROPOSED) n++;
|
|
590
|
+
return n;
|
|
591
|
+
}
|
|
468
592
|
export function createSgEdgeV2({ id, nodeId, targetId, metadata } = {}) {
|
|
469
|
-
if (!id) throw new Error("sg edge id required");
|
|
593
|
+
if (!id) throw new Error("sg edge id required");
|
|
594
|
+
if (!nodeId) throw new Error("sg edge nodeId required");
|
|
470
595
|
if (_sgEsV2.has(id)) throw new Error(`sg edge ${id} already exists`);
|
|
471
596
|
if (!_sgNsV2.has(nodeId)) throw new Error(`sg node ${nodeId} not found`);
|
|
472
|
-
if (_sgCountPending(nodeId) >= _sgMaxPendingEdgesPerNode)
|
|
597
|
+
if (_sgCountPending(nodeId) >= _sgMaxPendingEdgesPerNode)
|
|
598
|
+
throw new Error(`max pending sg edges for node ${nodeId} reached`);
|
|
599
|
+
const now = Date.now();
|
|
600
|
+
const e = {
|
|
601
|
+
id,
|
|
602
|
+
nodeId,
|
|
603
|
+
targetId: targetId || "",
|
|
604
|
+
status: SG_EDGE_LIFECYCLE_V2.PROPOSED,
|
|
605
|
+
createdAt: now,
|
|
606
|
+
updatedAt: now,
|
|
607
|
+
startedAt: now,
|
|
608
|
+
settledAt: null,
|
|
609
|
+
metadata: { ...(metadata || {}) },
|
|
610
|
+
};
|
|
611
|
+
_sgEsV2.set(id, e);
|
|
612
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
613
|
+
}
|
|
614
|
+
export function establishSgEdgeV2(id) {
|
|
615
|
+
const e = _sgEsV2.get(id);
|
|
616
|
+
if (!e) throw new Error(`sg edge ${id} not found`);
|
|
617
|
+
_sgCheckE(e.status, SG_EDGE_LIFECYCLE_V2.ESTABLISHED);
|
|
618
|
+
const now = Date.now();
|
|
619
|
+
e.status = SG_EDGE_LIFECYCLE_V2.ESTABLISHED;
|
|
620
|
+
e.updatedAt = now;
|
|
621
|
+
if (!e.settledAt) e.settledAt = now;
|
|
622
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
623
|
+
}
|
|
624
|
+
export function severSgEdgeV2(id, reason) {
|
|
625
|
+
const e = _sgEsV2.get(id);
|
|
626
|
+
if (!e) throw new Error(`sg edge ${id} not found`);
|
|
627
|
+
_sgCheckE(e.status, SG_EDGE_LIFECYCLE_V2.SEVERED);
|
|
628
|
+
const now = Date.now();
|
|
629
|
+
e.status = SG_EDGE_LIFECYCLE_V2.SEVERED;
|
|
630
|
+
e.updatedAt = now;
|
|
631
|
+
if (reason) e.metadata.severReason = String(reason);
|
|
632
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
633
|
+
}
|
|
634
|
+
export function expireSgEdgeV2(id) {
|
|
635
|
+
const e = _sgEsV2.get(id);
|
|
636
|
+
if (!e) throw new Error(`sg edge ${id} not found`);
|
|
637
|
+
_sgCheckE(e.status, SG_EDGE_LIFECYCLE_V2.EXPIRED);
|
|
638
|
+
const now = Date.now();
|
|
639
|
+
e.status = SG_EDGE_LIFECYCLE_V2.EXPIRED;
|
|
640
|
+
e.updatedAt = now;
|
|
641
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
642
|
+
}
|
|
643
|
+
export function cancelSgEdgeV2(id, reason) {
|
|
644
|
+
const e = _sgEsV2.get(id);
|
|
645
|
+
if (!e) throw new Error(`sg edge ${id} not found`);
|
|
646
|
+
_sgCheckE(e.status, SG_EDGE_LIFECYCLE_V2.CANCELLED);
|
|
473
647
|
const now = Date.now();
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
export function
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
648
|
+
e.status = SG_EDGE_LIFECYCLE_V2.CANCELLED;
|
|
649
|
+
e.updatedAt = now;
|
|
650
|
+
if (!e.settledAt) e.settledAt = now;
|
|
651
|
+
if (reason) e.metadata.cancelReason = String(reason);
|
|
652
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
653
|
+
}
|
|
654
|
+
export function getSgEdgeV2(id) {
|
|
655
|
+
const e = _sgEsV2.get(id);
|
|
656
|
+
if (!e) return null;
|
|
657
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
658
|
+
}
|
|
659
|
+
export function listSgEdgesV2() {
|
|
660
|
+
return [..._sgEsV2.values()].map((e) => ({
|
|
661
|
+
...e,
|
|
662
|
+
metadata: { ...e.metadata },
|
|
663
|
+
}));
|
|
664
|
+
}
|
|
665
|
+
export function autoDeactivateIdleSgNodesV2({ now } = {}) {
|
|
666
|
+
const t = now ?? Date.now();
|
|
667
|
+
const flipped = [];
|
|
668
|
+
for (const n of _sgNsV2.values())
|
|
669
|
+
if (
|
|
670
|
+
n.status === SG_NODE_MATURITY_V2.ACTIVE &&
|
|
671
|
+
t - n.lastTouchedAt >= _sgIdleMs
|
|
672
|
+
) {
|
|
673
|
+
n.status = SG_NODE_MATURITY_V2.INACTIVE;
|
|
674
|
+
n.updatedAt = t;
|
|
675
|
+
flipped.push(n.id);
|
|
676
|
+
}
|
|
677
|
+
return { flipped, count: flipped.length };
|
|
678
|
+
}
|
|
679
|
+
export function autoExpireStaleSgEdgesV2({ now } = {}) {
|
|
680
|
+
const t = now ?? Date.now();
|
|
681
|
+
const flipped = [];
|
|
682
|
+
for (const e of _sgEsV2.values())
|
|
683
|
+
if (
|
|
684
|
+
e.status === SG_EDGE_LIFECYCLE_V2.PROPOSED &&
|
|
685
|
+
t - e.startedAt >= _sgStuckMs
|
|
686
|
+
) {
|
|
687
|
+
e.status = SG_EDGE_LIFECYCLE_V2.CANCELLED;
|
|
688
|
+
e.updatedAt = t;
|
|
689
|
+
if (!e.settledAt) e.settledAt = t;
|
|
690
|
+
e.metadata.cancelReason = "auto-cancel-stale";
|
|
691
|
+
flipped.push(e.id);
|
|
692
|
+
}
|
|
693
|
+
return { flipped, count: flipped.length };
|
|
694
|
+
}
|
|
485
695
|
export function getSocialGraphGovStatsV2() {
|
|
486
|
-
const nodesByStatus = {};
|
|
487
|
-
|
|
488
|
-
|
|
696
|
+
const nodesByStatus = {};
|
|
697
|
+
for (const v of Object.values(SG_NODE_MATURITY_V2)) nodesByStatus[v] = 0;
|
|
698
|
+
for (const n of _sgNsV2.values()) nodesByStatus[n.status]++;
|
|
699
|
+
const edgesByStatus = {};
|
|
700
|
+
for (const v of Object.values(SG_EDGE_LIFECYCLE_V2)) edgesByStatus[v] = 0;
|
|
701
|
+
for (const e of _sgEsV2.values()) edgesByStatus[e.status]++;
|
|
702
|
+
return {
|
|
703
|
+
totalSgNodesV2: _sgNsV2.size,
|
|
704
|
+
totalSgEdgesV2: _sgEsV2.size,
|
|
705
|
+
maxActiveSgNodesPerOwner: _sgMaxActivePerOwner,
|
|
706
|
+
maxPendingSgEdgesPerNode: _sgMaxPendingEdgesPerNode,
|
|
707
|
+
sgNodeIdleMs: _sgIdleMs,
|
|
708
|
+
sgEdgeStuckMs: _sgStuckMs,
|
|
709
|
+
nodesByStatus,
|
|
710
|
+
edgesByStatus,
|
|
711
|
+
};
|
|
489
712
|
}
|
|
@@ -607,3 +607,333 @@ export function _resetStateSocialManagerV2() {
|
|
|
607
607
|
_relationshipIdleMsV2 = SOCIAL_DEFAULT_RELATIONSHIP_IDLE_MS;
|
|
608
608
|
_threadStuckMsV2 = SOCIAL_DEFAULT_THREAD_STUCK_MS;
|
|
609
609
|
}
|
|
610
|
+
|
|
611
|
+
// =====================================================================
|
|
612
|
+
// social-manager V2 governance overlay (iter22)
|
|
613
|
+
// =====================================================================
|
|
614
|
+
export const SMGOV_PROFILE_MATURITY_V2 = Object.freeze({
|
|
615
|
+
PENDING: "pending",
|
|
616
|
+
ACTIVE: "active",
|
|
617
|
+
MUTED: "muted",
|
|
618
|
+
ARCHIVED: "archived",
|
|
619
|
+
});
|
|
620
|
+
export const SMGOV_POST_LIFECYCLE_V2 = Object.freeze({
|
|
621
|
+
QUEUED: "queued",
|
|
622
|
+
POSTING: "posting",
|
|
623
|
+
POSTED: "posted",
|
|
624
|
+
FAILED: "failed",
|
|
625
|
+
CANCELLED: "cancelled",
|
|
626
|
+
});
|
|
627
|
+
const _smgovPTrans = new Map([
|
|
628
|
+
[
|
|
629
|
+
SMGOV_PROFILE_MATURITY_V2.PENDING,
|
|
630
|
+
new Set([
|
|
631
|
+
SMGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
632
|
+
SMGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
633
|
+
]),
|
|
634
|
+
],
|
|
635
|
+
[
|
|
636
|
+
SMGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
637
|
+
new Set([
|
|
638
|
+
SMGOV_PROFILE_MATURITY_V2.MUTED,
|
|
639
|
+
SMGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
640
|
+
]),
|
|
641
|
+
],
|
|
642
|
+
[
|
|
643
|
+
SMGOV_PROFILE_MATURITY_V2.MUTED,
|
|
644
|
+
new Set([
|
|
645
|
+
SMGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
646
|
+
SMGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
647
|
+
]),
|
|
648
|
+
],
|
|
649
|
+
[SMGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
650
|
+
]);
|
|
651
|
+
const _smgovPTerminal = new Set([SMGOV_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
652
|
+
const _smgovJTrans = new Map([
|
|
653
|
+
[
|
|
654
|
+
SMGOV_POST_LIFECYCLE_V2.QUEUED,
|
|
655
|
+
new Set([
|
|
656
|
+
SMGOV_POST_LIFECYCLE_V2.POSTING,
|
|
657
|
+
SMGOV_POST_LIFECYCLE_V2.CANCELLED,
|
|
658
|
+
]),
|
|
659
|
+
],
|
|
660
|
+
[
|
|
661
|
+
SMGOV_POST_LIFECYCLE_V2.POSTING,
|
|
662
|
+
new Set([
|
|
663
|
+
SMGOV_POST_LIFECYCLE_V2.POSTED,
|
|
664
|
+
SMGOV_POST_LIFECYCLE_V2.FAILED,
|
|
665
|
+
SMGOV_POST_LIFECYCLE_V2.CANCELLED,
|
|
666
|
+
]),
|
|
667
|
+
],
|
|
668
|
+
[SMGOV_POST_LIFECYCLE_V2.POSTED, new Set()],
|
|
669
|
+
[SMGOV_POST_LIFECYCLE_V2.FAILED, new Set()],
|
|
670
|
+
[SMGOV_POST_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
671
|
+
]);
|
|
672
|
+
const _smgovPsV2 = new Map();
|
|
673
|
+
const _smgovJsV2 = new Map();
|
|
674
|
+
let _smgovMaxActive = 10,
|
|
675
|
+
_smgovMaxPending = 30,
|
|
676
|
+
_smgovIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
677
|
+
_smgovStuckMs = 60 * 1000;
|
|
678
|
+
function _smgovPos(n, label) {
|
|
679
|
+
const v = Math.floor(Number(n));
|
|
680
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
681
|
+
throw new Error(`${label} must be positive integer`);
|
|
682
|
+
return v;
|
|
683
|
+
}
|
|
684
|
+
function _smgovCheckP(from, to) {
|
|
685
|
+
const a = _smgovPTrans.get(from);
|
|
686
|
+
if (!a || !a.has(to))
|
|
687
|
+
throw new Error(`invalid smgov profile transition ${from} → ${to}`);
|
|
688
|
+
}
|
|
689
|
+
function _smgovCheckJ(from, to) {
|
|
690
|
+
const a = _smgovJTrans.get(from);
|
|
691
|
+
if (!a || !a.has(to))
|
|
692
|
+
throw new Error(`invalid smgov post transition ${from} → ${to}`);
|
|
693
|
+
}
|
|
694
|
+
function _smgovCountActive(owner) {
|
|
695
|
+
let c = 0;
|
|
696
|
+
for (const p of _smgovPsV2.values())
|
|
697
|
+
if (p.owner === owner && p.status === SMGOV_PROFILE_MATURITY_V2.ACTIVE) c++;
|
|
698
|
+
return c;
|
|
699
|
+
}
|
|
700
|
+
function _smgovCountPending(profileId) {
|
|
701
|
+
let c = 0;
|
|
702
|
+
for (const j of _smgovJsV2.values())
|
|
703
|
+
if (
|
|
704
|
+
j.profileId === profileId &&
|
|
705
|
+
(j.status === SMGOV_POST_LIFECYCLE_V2.QUEUED ||
|
|
706
|
+
j.status === SMGOV_POST_LIFECYCLE_V2.POSTING)
|
|
707
|
+
)
|
|
708
|
+
c++;
|
|
709
|
+
return c;
|
|
710
|
+
}
|
|
711
|
+
export function setMaxActiveSmgovProfilesPerOwnerV2(n) {
|
|
712
|
+
_smgovMaxActive = _smgovPos(n, "maxActiveSmgovProfilesPerOwner");
|
|
713
|
+
}
|
|
714
|
+
export function getMaxActiveSmgovProfilesPerOwnerV2() {
|
|
715
|
+
return _smgovMaxActive;
|
|
716
|
+
}
|
|
717
|
+
export function setMaxPendingSmgovPostsPerProfileV2(n) {
|
|
718
|
+
_smgovMaxPending = _smgovPos(n, "maxPendingSmgovPostsPerProfile");
|
|
719
|
+
}
|
|
720
|
+
export function getMaxPendingSmgovPostsPerProfileV2() {
|
|
721
|
+
return _smgovMaxPending;
|
|
722
|
+
}
|
|
723
|
+
export function setSmgovProfileIdleMsV2(n) {
|
|
724
|
+
_smgovIdleMs = _smgovPos(n, "smgovProfileIdleMs");
|
|
725
|
+
}
|
|
726
|
+
export function getSmgovProfileIdleMsV2() {
|
|
727
|
+
return _smgovIdleMs;
|
|
728
|
+
}
|
|
729
|
+
export function setSmgovPostStuckMsV2(n) {
|
|
730
|
+
_smgovStuckMs = _smgovPos(n, "smgovPostStuckMs");
|
|
731
|
+
}
|
|
732
|
+
export function getSmgovPostStuckMsV2() {
|
|
733
|
+
return _smgovStuckMs;
|
|
734
|
+
}
|
|
735
|
+
export function _resetStateSocialManagerGovV2() {
|
|
736
|
+
_smgovPsV2.clear();
|
|
737
|
+
_smgovJsV2.clear();
|
|
738
|
+
_smgovMaxActive = 10;
|
|
739
|
+
_smgovMaxPending = 30;
|
|
740
|
+
_smgovIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
741
|
+
_smgovStuckMs = 60 * 1000;
|
|
742
|
+
}
|
|
743
|
+
export function registerSmgovProfileV2({ id, owner, channel, metadata } = {}) {
|
|
744
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
745
|
+
if (_smgovPsV2.has(id)) throw new Error(`smgov profile ${id} already exists`);
|
|
746
|
+
const now = Date.now();
|
|
747
|
+
const p = {
|
|
748
|
+
id,
|
|
749
|
+
owner,
|
|
750
|
+
channel: channel || "timeline",
|
|
751
|
+
status: SMGOV_PROFILE_MATURITY_V2.PENDING,
|
|
752
|
+
createdAt: now,
|
|
753
|
+
updatedAt: now,
|
|
754
|
+
lastTouchedAt: now,
|
|
755
|
+
activatedAt: null,
|
|
756
|
+
archivedAt: null,
|
|
757
|
+
metadata: { ...(metadata || {}) },
|
|
758
|
+
};
|
|
759
|
+
_smgovPsV2.set(id, p);
|
|
760
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
761
|
+
}
|
|
762
|
+
export function activateSmgovProfileV2(id) {
|
|
763
|
+
const p = _smgovPsV2.get(id);
|
|
764
|
+
if (!p) throw new Error(`smgov profile ${id} not found`);
|
|
765
|
+
const isInitial = p.status === SMGOV_PROFILE_MATURITY_V2.PENDING;
|
|
766
|
+
_smgovCheckP(p.status, SMGOV_PROFILE_MATURITY_V2.ACTIVE);
|
|
767
|
+
if (isInitial && _smgovCountActive(p.owner) >= _smgovMaxActive)
|
|
768
|
+
throw new Error(`max active smgov profiles for owner ${p.owner} reached`);
|
|
769
|
+
const now = Date.now();
|
|
770
|
+
p.status = SMGOV_PROFILE_MATURITY_V2.ACTIVE;
|
|
771
|
+
p.updatedAt = now;
|
|
772
|
+
p.lastTouchedAt = now;
|
|
773
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
774
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
775
|
+
}
|
|
776
|
+
export function muteSmgovProfileV2(id) {
|
|
777
|
+
const p = _smgovPsV2.get(id);
|
|
778
|
+
if (!p) throw new Error(`smgov profile ${id} not found`);
|
|
779
|
+
_smgovCheckP(p.status, SMGOV_PROFILE_MATURITY_V2.MUTED);
|
|
780
|
+
p.status = SMGOV_PROFILE_MATURITY_V2.MUTED;
|
|
781
|
+
p.updatedAt = Date.now();
|
|
782
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
783
|
+
}
|
|
784
|
+
export function archiveSmgovProfileV2(id) {
|
|
785
|
+
const p = _smgovPsV2.get(id);
|
|
786
|
+
if (!p) throw new Error(`smgov profile ${id} not found`);
|
|
787
|
+
_smgovCheckP(p.status, SMGOV_PROFILE_MATURITY_V2.ARCHIVED);
|
|
788
|
+
const now = Date.now();
|
|
789
|
+
p.status = SMGOV_PROFILE_MATURITY_V2.ARCHIVED;
|
|
790
|
+
p.updatedAt = now;
|
|
791
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
792
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
793
|
+
}
|
|
794
|
+
export function touchSmgovProfileV2(id) {
|
|
795
|
+
const p = _smgovPsV2.get(id);
|
|
796
|
+
if (!p) throw new Error(`smgov profile ${id} not found`);
|
|
797
|
+
if (_smgovPTerminal.has(p.status))
|
|
798
|
+
throw new Error(`cannot touch terminal smgov profile ${id}`);
|
|
799
|
+
const now = Date.now();
|
|
800
|
+
p.lastTouchedAt = now;
|
|
801
|
+
p.updatedAt = now;
|
|
802
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
803
|
+
}
|
|
804
|
+
export function getSmgovProfileV2(id) {
|
|
805
|
+
const p = _smgovPsV2.get(id);
|
|
806
|
+
if (!p) return null;
|
|
807
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
808
|
+
}
|
|
809
|
+
export function listSmgovProfilesV2() {
|
|
810
|
+
return [..._smgovPsV2.values()].map((p) => ({
|
|
811
|
+
...p,
|
|
812
|
+
metadata: { ...p.metadata },
|
|
813
|
+
}));
|
|
814
|
+
}
|
|
815
|
+
export function createSmgovPostV2({ id, profileId, author, metadata } = {}) {
|
|
816
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
817
|
+
if (_smgovJsV2.has(id)) throw new Error(`smgov post ${id} already exists`);
|
|
818
|
+
if (!_smgovPsV2.has(profileId))
|
|
819
|
+
throw new Error(`smgov profile ${profileId} not found`);
|
|
820
|
+
if (_smgovCountPending(profileId) >= _smgovMaxPending)
|
|
821
|
+
throw new Error(`max pending smgov posts for profile ${profileId} reached`);
|
|
822
|
+
const now = Date.now();
|
|
823
|
+
const j = {
|
|
824
|
+
id,
|
|
825
|
+
profileId,
|
|
826
|
+
author: author || "",
|
|
827
|
+
status: SMGOV_POST_LIFECYCLE_V2.QUEUED,
|
|
828
|
+
createdAt: now,
|
|
829
|
+
updatedAt: now,
|
|
830
|
+
startedAt: null,
|
|
831
|
+
settledAt: null,
|
|
832
|
+
metadata: { ...(metadata || {}) },
|
|
833
|
+
};
|
|
834
|
+
_smgovJsV2.set(id, j);
|
|
835
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
836
|
+
}
|
|
837
|
+
export function postingSmgovPostV2(id) {
|
|
838
|
+
const j = _smgovJsV2.get(id);
|
|
839
|
+
if (!j) throw new Error(`smgov post ${id} not found`);
|
|
840
|
+
_smgovCheckJ(j.status, SMGOV_POST_LIFECYCLE_V2.POSTING);
|
|
841
|
+
const now = Date.now();
|
|
842
|
+
j.status = SMGOV_POST_LIFECYCLE_V2.POSTING;
|
|
843
|
+
j.updatedAt = now;
|
|
844
|
+
if (!j.startedAt) j.startedAt = now;
|
|
845
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
846
|
+
}
|
|
847
|
+
export function completePostSmgovV2(id) {
|
|
848
|
+
const j = _smgovJsV2.get(id);
|
|
849
|
+
if (!j) throw new Error(`smgov post ${id} not found`);
|
|
850
|
+
_smgovCheckJ(j.status, SMGOV_POST_LIFECYCLE_V2.POSTED);
|
|
851
|
+
const now = Date.now();
|
|
852
|
+
j.status = SMGOV_POST_LIFECYCLE_V2.POSTED;
|
|
853
|
+
j.updatedAt = now;
|
|
854
|
+
if (!j.settledAt) j.settledAt = now;
|
|
855
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
856
|
+
}
|
|
857
|
+
export function failSmgovPostV2(id, reason) {
|
|
858
|
+
const j = _smgovJsV2.get(id);
|
|
859
|
+
if (!j) throw new Error(`smgov post ${id} not found`);
|
|
860
|
+
_smgovCheckJ(j.status, SMGOV_POST_LIFECYCLE_V2.FAILED);
|
|
861
|
+
const now = Date.now();
|
|
862
|
+
j.status = SMGOV_POST_LIFECYCLE_V2.FAILED;
|
|
863
|
+
j.updatedAt = now;
|
|
864
|
+
if (!j.settledAt) j.settledAt = now;
|
|
865
|
+
if (reason) j.metadata.failReason = String(reason);
|
|
866
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
867
|
+
}
|
|
868
|
+
export function cancelSmgovPostV2(id, reason) {
|
|
869
|
+
const j = _smgovJsV2.get(id);
|
|
870
|
+
if (!j) throw new Error(`smgov post ${id} not found`);
|
|
871
|
+
_smgovCheckJ(j.status, SMGOV_POST_LIFECYCLE_V2.CANCELLED);
|
|
872
|
+
const now = Date.now();
|
|
873
|
+
j.status = SMGOV_POST_LIFECYCLE_V2.CANCELLED;
|
|
874
|
+
j.updatedAt = now;
|
|
875
|
+
if (!j.settledAt) j.settledAt = now;
|
|
876
|
+
if (reason) j.metadata.cancelReason = String(reason);
|
|
877
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
878
|
+
}
|
|
879
|
+
export function getSmgovPostV2(id) {
|
|
880
|
+
const j = _smgovJsV2.get(id);
|
|
881
|
+
if (!j) return null;
|
|
882
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
883
|
+
}
|
|
884
|
+
export function listSmgovPostsV2() {
|
|
885
|
+
return [..._smgovJsV2.values()].map((j) => ({
|
|
886
|
+
...j,
|
|
887
|
+
metadata: { ...j.metadata },
|
|
888
|
+
}));
|
|
889
|
+
}
|
|
890
|
+
export function autoMuteIdleSmgovProfilesV2({ now } = {}) {
|
|
891
|
+
const t = now ?? Date.now();
|
|
892
|
+
const flipped = [];
|
|
893
|
+
for (const p of _smgovPsV2.values())
|
|
894
|
+
if (
|
|
895
|
+
p.status === SMGOV_PROFILE_MATURITY_V2.ACTIVE &&
|
|
896
|
+
t - p.lastTouchedAt >= _smgovIdleMs
|
|
897
|
+
) {
|
|
898
|
+
p.status = SMGOV_PROFILE_MATURITY_V2.MUTED;
|
|
899
|
+
p.updatedAt = t;
|
|
900
|
+
flipped.push(p.id);
|
|
901
|
+
}
|
|
902
|
+
return { flipped, count: flipped.length };
|
|
903
|
+
}
|
|
904
|
+
export function autoFailStuckSmgovPostsV2({ now } = {}) {
|
|
905
|
+
const t = now ?? Date.now();
|
|
906
|
+
const flipped = [];
|
|
907
|
+
for (const j of _smgovJsV2.values())
|
|
908
|
+
if (
|
|
909
|
+
j.status === SMGOV_POST_LIFECYCLE_V2.POSTING &&
|
|
910
|
+
j.startedAt != null &&
|
|
911
|
+
t - j.startedAt >= _smgovStuckMs
|
|
912
|
+
) {
|
|
913
|
+
j.status = SMGOV_POST_LIFECYCLE_V2.FAILED;
|
|
914
|
+
j.updatedAt = t;
|
|
915
|
+
if (!j.settledAt) j.settledAt = t;
|
|
916
|
+
j.metadata.failReason = "auto-fail-stuck";
|
|
917
|
+
flipped.push(j.id);
|
|
918
|
+
}
|
|
919
|
+
return { flipped, count: flipped.length };
|
|
920
|
+
}
|
|
921
|
+
export function getSocialManagerGovStatsV2() {
|
|
922
|
+
const profilesByStatus = {};
|
|
923
|
+
for (const v of Object.values(SMGOV_PROFILE_MATURITY_V2))
|
|
924
|
+
profilesByStatus[v] = 0;
|
|
925
|
+
for (const p of _smgovPsV2.values()) profilesByStatus[p.status]++;
|
|
926
|
+
const postsByStatus = {};
|
|
927
|
+
for (const v of Object.values(SMGOV_POST_LIFECYCLE_V2)) postsByStatus[v] = 0;
|
|
928
|
+
for (const j of _smgovJsV2.values()) postsByStatus[j.status]++;
|
|
929
|
+
return {
|
|
930
|
+
totalSmgovProfilesV2: _smgovPsV2.size,
|
|
931
|
+
totalSmgovPostsV2: _smgovJsV2.size,
|
|
932
|
+
maxActiveSmgovProfilesPerOwner: _smgovMaxActive,
|
|
933
|
+
maxPendingSmgovPostsPerProfile: _smgovMaxPending,
|
|
934
|
+
smgovProfileIdleMs: _smgovIdleMs,
|
|
935
|
+
smgovPostStuckMs: _smgovStuckMs,
|
|
936
|
+
profilesByStatus,
|
|
937
|
+
postsByStatus,
|
|
938
|
+
};
|
|
939
|
+
}
|