chainlesschain 0.51.0 → 0.66.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/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AppLayout-Rvi759IS.js → AppLayout-6SPt_8Y_.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-DBhFxXYQ.js → Dashboard-Br7kCwKJ.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +1 -0
- package/src/assets/web-panel/assets/{index-uL0cZ8N_.js → index-tN-8TosE.js} +2 -2
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/agent-network.js +785 -0
- package/src/commands/automation.js +654 -0
- package/src/commands/dao.js +565 -0
- package/src/commands/did-v2.js +620 -0
- package/src/commands/economy.js +578 -0
- package/src/commands/evolution.js +391 -0
- package/src/commands/hmemory.js +442 -0
- package/src/commands/perf.js +433 -0
- package/src/commands/pipeline.js +449 -0
- package/src/commands/plugin-ecosystem.js +517 -0
- package/src/commands/sandbox.js +401 -0
- package/src/commands/social.js +311 -0
- package/src/commands/sso.js +798 -0
- package/src/commands/workflow.js +320 -0
- package/src/commands/zkp.js +227 -1
- package/src/index.js +21 -0
- package/src/lib/agent-economy.js +479 -0
- package/src/lib/agent-network.js +1121 -0
- package/src/lib/automation-engine.js +948 -0
- package/src/lib/dao-governance.js +569 -0
- package/src/lib/did-v2-manager.js +1127 -0
- package/src/lib/evolution-system.js +453 -0
- package/src/lib/hierarchical-memory.js +481 -0
- package/src/lib/perf-tuning.js +734 -0
- package/src/lib/pipeline-orchestrator.js +928 -0
- package/src/lib/plugin-ecosystem.js +1109 -0
- package/src/lib/sandbox-v2.js +306 -0
- package/src/lib/social-graph-analytics.js +707 -0
- package/src/lib/sso-manager.js +841 -0
- package/src/lib/workflow-engine.js +454 -1
- package/src/lib/zkp-engine.js +249 -20
- package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
package/src/commands/social.js
CHANGED
|
@@ -35,6 +35,18 @@ import {
|
|
|
35
35
|
subscribe as graphSubscribe,
|
|
36
36
|
EDGE_TYPES,
|
|
37
37
|
} from "../lib/social-graph.js";
|
|
38
|
+
import {
|
|
39
|
+
METRICS as ANALYTICS_METRICS,
|
|
40
|
+
degreeCentrality,
|
|
41
|
+
closenessCentrality,
|
|
42
|
+
betweennessCentrality,
|
|
43
|
+
eigenvectorCentrality,
|
|
44
|
+
influenceScore,
|
|
45
|
+
detectCommunities,
|
|
46
|
+
shortestPath,
|
|
47
|
+
topByMetric,
|
|
48
|
+
analyticsStats,
|
|
49
|
+
} from "../lib/social-graph-analytics.js";
|
|
38
50
|
|
|
39
51
|
export function registerSocialCommand(program) {
|
|
40
52
|
const social = program
|
|
@@ -742,4 +754,303 @@ export function registerSocialCommand(program) {
|
|
|
742
754
|
process.exit(1);
|
|
743
755
|
}
|
|
744
756
|
});
|
|
757
|
+
|
|
758
|
+
// ── Graph analytics (Phase 42) ──────────────────────────────
|
|
759
|
+
|
|
760
|
+
async function _loadSnapshot(options) {
|
|
761
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
762
|
+
if (!ctx.db) {
|
|
763
|
+
logger.error("Database not available");
|
|
764
|
+
process.exit(1);
|
|
765
|
+
}
|
|
766
|
+
const db = ctx.db.getDatabase();
|
|
767
|
+
ensureGraphTables(db);
|
|
768
|
+
graphLoadFromDb(db);
|
|
769
|
+
return getGraphSnapshot({ edgeType: options.type });
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
function _splitEdgeTypes(list) {
|
|
773
|
+
if (!list) return undefined;
|
|
774
|
+
return list
|
|
775
|
+
.split(",")
|
|
776
|
+
.map((s) => s.trim())
|
|
777
|
+
.filter(Boolean);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
function _printScoreMap(scores, limit) {
|
|
781
|
+
const entries = Object.entries(scores).sort((a, b) => {
|
|
782
|
+
if (b[1] !== a[1]) return b[1] - a[1];
|
|
783
|
+
return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;
|
|
784
|
+
});
|
|
785
|
+
const slice = limit > 0 ? entries.slice(0, limit) : entries;
|
|
786
|
+
for (const [did, score] of slice) {
|
|
787
|
+
console.log(`${chalk.cyan(did.padEnd(28))} ${score.toFixed(6)}`);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
graph
|
|
792
|
+
.command("degree")
|
|
793
|
+
.description("Degree centrality per DID")
|
|
794
|
+
.option("-d, --direction <in|out|both>", "Edge direction", "both")
|
|
795
|
+
.option("--no-normalize", "Disable normalization by (n-1)")
|
|
796
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types to include")
|
|
797
|
+
.option("-l, --limit <n>", "Show top N", "10")
|
|
798
|
+
.option("--json", "Output as JSON")
|
|
799
|
+
.action(async (options) => {
|
|
800
|
+
try {
|
|
801
|
+
const snap = await _loadSnapshot(options);
|
|
802
|
+
const scores = degreeCentrality(snap, {
|
|
803
|
+
direction: options.direction,
|
|
804
|
+
normalize: options.normalize !== false,
|
|
805
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
806
|
+
});
|
|
807
|
+
if (options.json) console.log(JSON.stringify(scores, null, 2));
|
|
808
|
+
else _printScoreMap(scores, parseInt(options.limit, 10) || 10);
|
|
809
|
+
await shutdown();
|
|
810
|
+
} catch (err) {
|
|
811
|
+
logger.error(`Failed: ${err.message}`);
|
|
812
|
+
process.exit(1);
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
graph
|
|
817
|
+
.command("closeness")
|
|
818
|
+
.description("Harmonic closeness centrality per DID")
|
|
819
|
+
.option("--directed", "Treat graph as directed")
|
|
820
|
+
.option("--no-normalize", "Disable normalization by (n-1)")
|
|
821
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types")
|
|
822
|
+
.option("-l, --limit <n>", "Show top N", "10")
|
|
823
|
+
.option("--json", "Output as JSON")
|
|
824
|
+
.action(async (options) => {
|
|
825
|
+
try {
|
|
826
|
+
const snap = await _loadSnapshot(options);
|
|
827
|
+
const scores = closenessCentrality(snap, {
|
|
828
|
+
directed: !!options.directed,
|
|
829
|
+
normalize: options.normalize !== false,
|
|
830
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
831
|
+
});
|
|
832
|
+
if (options.json) console.log(JSON.stringify(scores, null, 2));
|
|
833
|
+
else _printScoreMap(scores, parseInt(options.limit, 10) || 10);
|
|
834
|
+
await shutdown();
|
|
835
|
+
} catch (err) {
|
|
836
|
+
logger.error(`Failed: ${err.message}`);
|
|
837
|
+
process.exit(1);
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
graph
|
|
842
|
+
.command("betweenness")
|
|
843
|
+
.description("Betweenness centrality (Brandes' algorithm)")
|
|
844
|
+
.option("--directed", "Treat graph as directed")
|
|
845
|
+
.option("--no-normalize", "Disable normalization")
|
|
846
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types")
|
|
847
|
+
.option("-l, --limit <n>", "Show top N", "10")
|
|
848
|
+
.option("--json", "Output as JSON")
|
|
849
|
+
.action(async (options) => {
|
|
850
|
+
try {
|
|
851
|
+
const snap = await _loadSnapshot(options);
|
|
852
|
+
const scores = betweennessCentrality(snap, {
|
|
853
|
+
directed: !!options.directed,
|
|
854
|
+
normalize: options.normalize !== false,
|
|
855
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
856
|
+
});
|
|
857
|
+
if (options.json) console.log(JSON.stringify(scores, null, 2));
|
|
858
|
+
else _printScoreMap(scores, parseInt(options.limit, 10) || 10);
|
|
859
|
+
await shutdown();
|
|
860
|
+
} catch (err) {
|
|
861
|
+
logger.error(`Failed: ${err.message}`);
|
|
862
|
+
process.exit(1);
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
graph
|
|
867
|
+
.command("eigenvector")
|
|
868
|
+
.description("Eigenvector centrality via power iteration")
|
|
869
|
+
.option("--directed", "Treat graph as directed")
|
|
870
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types")
|
|
871
|
+
.option("--iterations <n>", "Max iterations", "100")
|
|
872
|
+
.option("--tolerance <f>", "Convergence tolerance", "1e-6")
|
|
873
|
+
.option("-l, --limit <n>", "Show top N", "10")
|
|
874
|
+
.option("--json", "Output as JSON")
|
|
875
|
+
.action(async (options) => {
|
|
876
|
+
try {
|
|
877
|
+
const snap = await _loadSnapshot(options);
|
|
878
|
+
const scores = eigenvectorCentrality(snap, {
|
|
879
|
+
directed: !!options.directed,
|
|
880
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
881
|
+
iterations: parseInt(options.iterations, 10) || 100,
|
|
882
|
+
tolerance: parseFloat(options.tolerance) || 1e-6,
|
|
883
|
+
});
|
|
884
|
+
if (options.json) console.log(JSON.stringify(scores, null, 2));
|
|
885
|
+
else _printScoreMap(scores, parseInt(options.limit, 10) || 10);
|
|
886
|
+
await shutdown();
|
|
887
|
+
} catch (err) {
|
|
888
|
+
logger.error(`Failed: ${err.message}`);
|
|
889
|
+
process.exit(1);
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
|
|
893
|
+
graph
|
|
894
|
+
.command("influence")
|
|
895
|
+
.description("Composite influence score (weighted sum of 4 centralities)")
|
|
896
|
+
.option("--directed", "Treat graph as directed")
|
|
897
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types")
|
|
898
|
+
.option("--w-degree <f>", "Weight for degree", "0.25")
|
|
899
|
+
.option("--w-closeness <f>", "Weight for closeness", "0.25")
|
|
900
|
+
.option("--w-betweenness <f>", "Weight for betweenness", "0.25")
|
|
901
|
+
.option("--w-eigenvector <f>", "Weight for eigenvector", "0.25")
|
|
902
|
+
.option("-l, --limit <n>", "Show top N", "10")
|
|
903
|
+
.option("--json", "Output as JSON")
|
|
904
|
+
.action(async (options) => {
|
|
905
|
+
try {
|
|
906
|
+
const snap = await _loadSnapshot(options);
|
|
907
|
+
const scores = influenceScore(snap, {
|
|
908
|
+
directed: !!options.directed,
|
|
909
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
910
|
+
weights: {
|
|
911
|
+
degree: parseFloat(options.wDegree),
|
|
912
|
+
closeness: parseFloat(options.wCloseness),
|
|
913
|
+
betweenness: parseFloat(options.wBetweenness),
|
|
914
|
+
eigenvector: parseFloat(options.wEigenvector),
|
|
915
|
+
},
|
|
916
|
+
});
|
|
917
|
+
if (options.json) console.log(JSON.stringify(scores, null, 2));
|
|
918
|
+
else _printScoreMap(scores, parseInt(options.limit, 10) || 10);
|
|
919
|
+
await shutdown();
|
|
920
|
+
} catch (err) {
|
|
921
|
+
logger.error(`Failed: ${err.message}`);
|
|
922
|
+
process.exit(1);
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
|
|
926
|
+
graph
|
|
927
|
+
.command("communities")
|
|
928
|
+
.description("Label-propagation community detection")
|
|
929
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types")
|
|
930
|
+
.option("--max-iterations <n>", "Max propagation rounds", "20")
|
|
931
|
+
.option("--min-size <n>", "Drop communities smaller than this", "1")
|
|
932
|
+
.option("--json", "Output as JSON")
|
|
933
|
+
.action(async (options) => {
|
|
934
|
+
try {
|
|
935
|
+
const snap = await _loadSnapshot(options);
|
|
936
|
+
const result = detectCommunities(snap, {
|
|
937
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
938
|
+
maxIterations: parseInt(options.maxIterations, 10) || 20,
|
|
939
|
+
minSize: parseInt(options.minSize, 10) || 1,
|
|
940
|
+
});
|
|
941
|
+
if (options.json) {
|
|
942
|
+
console.log(JSON.stringify(result, null, 2));
|
|
943
|
+
} else {
|
|
944
|
+
console.log(
|
|
945
|
+
chalk.bold(
|
|
946
|
+
`Communities: ${result.communities.length} modularity: ${result.modularity.toFixed(4)}`,
|
|
947
|
+
),
|
|
948
|
+
);
|
|
949
|
+
for (const c of result.communities) {
|
|
950
|
+
console.log(
|
|
951
|
+
` ${chalk.cyan(c.id)} (size ${c.size}) ${c.members.join(", ")}`,
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
await shutdown();
|
|
956
|
+
} catch (err) {
|
|
957
|
+
logger.error(`Failed: ${err.message}`);
|
|
958
|
+
process.exit(1);
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
graph
|
|
963
|
+
.command("path <source> <target>")
|
|
964
|
+
.description("Shortest path between two DIDs (unweighted BFS)")
|
|
965
|
+
.option("--undirected", "Treat graph as undirected (default: directed)")
|
|
966
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types")
|
|
967
|
+
.option("--json", "Output as JSON")
|
|
968
|
+
.action(async (source, target, options) => {
|
|
969
|
+
try {
|
|
970
|
+
const snap = await _loadSnapshot(options);
|
|
971
|
+
const result = shortestPath(snap, source, target, {
|
|
972
|
+
directed: !options.undirected,
|
|
973
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
974
|
+
});
|
|
975
|
+
if (options.json) {
|
|
976
|
+
console.log(JSON.stringify(result, null, 2));
|
|
977
|
+
} else if (!result.found) {
|
|
978
|
+
console.log(chalk.yellow("No path found"));
|
|
979
|
+
} else {
|
|
980
|
+
console.log(
|
|
981
|
+
`${chalk.bold("distance")}: ${result.distance} ${result.path.join(" → ")}`,
|
|
982
|
+
);
|
|
983
|
+
}
|
|
984
|
+
await shutdown();
|
|
985
|
+
} catch (err) {
|
|
986
|
+
logger.error(`Failed: ${err.message}`);
|
|
987
|
+
process.exit(1);
|
|
988
|
+
}
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
graph
|
|
992
|
+
.command("top <metric>")
|
|
993
|
+
.description(`Top-N DIDs by metric (${ANALYTICS_METRICS.join("|")})`)
|
|
994
|
+
.option("--directed", "Treat graph as directed (where applicable)")
|
|
995
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types")
|
|
996
|
+
.option("-l, --limit <n>", "Limit", "10")
|
|
997
|
+
.option("--json", "Output as JSON")
|
|
998
|
+
.action(async (metric, options) => {
|
|
999
|
+
try {
|
|
1000
|
+
const snap = await _loadSnapshot(options);
|
|
1001
|
+
const rows = topByMetric(snap, metric, {
|
|
1002
|
+
directed: !!options.directed,
|
|
1003
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
1004
|
+
limit: parseInt(options.limit, 10) || 10,
|
|
1005
|
+
});
|
|
1006
|
+
if (options.json) {
|
|
1007
|
+
console.log(JSON.stringify(rows, null, 2));
|
|
1008
|
+
} else {
|
|
1009
|
+
for (const r of rows) {
|
|
1010
|
+
console.log(
|
|
1011
|
+
`${chalk.cyan(r.did.padEnd(28))} ${r.score.toFixed(6)}`,
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
await shutdown();
|
|
1016
|
+
} catch (err) {
|
|
1017
|
+
logger.error(`Failed: ${err.message}`);
|
|
1018
|
+
process.exit(1);
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
graph
|
|
1023
|
+
.command("analytics-stats")
|
|
1024
|
+
.description("Graph-wide analytics rollup (counts, density, top influence)")
|
|
1025
|
+
.option("-e, --edge-types <list>", "Comma-separated edge types")
|
|
1026
|
+
.option("--json", "Output as JSON")
|
|
1027
|
+
.action(async (options) => {
|
|
1028
|
+
try {
|
|
1029
|
+
const snap = await _loadSnapshot(options);
|
|
1030
|
+
const stats = analyticsStats(snap, {
|
|
1031
|
+
edgeTypes: _splitEdgeTypes(options.edgeTypes),
|
|
1032
|
+
});
|
|
1033
|
+
if (options.json) {
|
|
1034
|
+
console.log(JSON.stringify(stats, null, 2));
|
|
1035
|
+
} else {
|
|
1036
|
+
console.log(chalk.bold("Social Graph Analytics"));
|
|
1037
|
+
console.log(` Nodes: ${stats.nodeCount}`);
|
|
1038
|
+
console.log(` Edges: ${stats.edgeCount}`);
|
|
1039
|
+
console.log(` Density: ${stats.density.toFixed(4)}`);
|
|
1040
|
+
console.log(` Generated: ${stats.generatedAt}`);
|
|
1041
|
+
if (stats.topInfluence.length > 0) {
|
|
1042
|
+
console.log(chalk.bold("\nTop influence:"));
|
|
1043
|
+
for (const r of stats.topInfluence) {
|
|
1044
|
+
console.log(
|
|
1045
|
+
` ${chalk.cyan(r.did.padEnd(28))} ${r.score.toFixed(6)}`,
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
await shutdown();
|
|
1051
|
+
} catch (err) {
|
|
1052
|
+
logger.error(`Failed: ${err.message}`);
|
|
1053
|
+
process.exit(1);
|
|
1054
|
+
}
|
|
1055
|
+
});
|
|
745
1056
|
}
|