chainlesschain 0.37.12 → 0.40.1

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 (48) hide show
  1. package/package.json +3 -2
  2. package/src/commands/agent.js +7 -1
  3. package/src/commands/ask.js +24 -9
  4. package/src/commands/chat.js +7 -1
  5. package/src/commands/cli-anything.js +266 -0
  6. package/src/commands/compliance.js +216 -0
  7. package/src/commands/dao.js +312 -0
  8. package/src/commands/dlp.js +278 -0
  9. package/src/commands/evomap.js +558 -0
  10. package/src/commands/hardening.js +230 -0
  11. package/src/commands/matrix.js +168 -0
  12. package/src/commands/nostr.js +185 -0
  13. package/src/commands/pqc.js +162 -0
  14. package/src/commands/scim.js +218 -0
  15. package/src/commands/serve.js +109 -0
  16. package/src/commands/siem.js +156 -0
  17. package/src/commands/social.js +480 -0
  18. package/src/commands/terraform.js +148 -0
  19. package/src/constants.js +1 -0
  20. package/src/index.js +60 -0
  21. package/src/lib/autonomous-agent.js +487 -0
  22. package/src/lib/cli-anything-bridge.js +379 -0
  23. package/src/lib/cli-context-engineering.js +472 -0
  24. package/src/lib/compliance-manager.js +290 -0
  25. package/src/lib/content-recommender.js +205 -0
  26. package/src/lib/dao-governance.js +296 -0
  27. package/src/lib/dlp-engine.js +304 -0
  28. package/src/lib/evomap-client.js +135 -0
  29. package/src/lib/evomap-federation.js +240 -0
  30. package/src/lib/evomap-governance.js +250 -0
  31. package/src/lib/evomap-manager.js +227 -0
  32. package/src/lib/git-integration.js +1 -1
  33. package/src/lib/hardening-manager.js +275 -0
  34. package/src/lib/llm-providers.js +14 -1
  35. package/src/lib/matrix-bridge.js +196 -0
  36. package/src/lib/nostr-bridge.js +195 -0
  37. package/src/lib/permanent-memory.js +370 -0
  38. package/src/lib/plan-mode.js +211 -0
  39. package/src/lib/pqc-manager.js +196 -0
  40. package/src/lib/scim-manager.js +212 -0
  41. package/src/lib/session-manager.js +38 -0
  42. package/src/lib/siem-exporter.js +137 -0
  43. package/src/lib/social-manager.js +283 -0
  44. package/src/lib/task-model-selector.js +232 -0
  45. package/src/lib/terraform-manager.js +201 -0
  46. package/src/lib/ws-server.js +474 -0
  47. package/src/repl/agent-repl.js +796 -41
  48. package/src/repl/chat-repl.js +14 -6
@@ -0,0 +1,558 @@
1
+ /**
2
+ * EvoMap commands — gene exchange protocol client
3
+ * chainlesschain evomap search|publish|download|list|hubs
4
+ */
5
+
6
+ import chalk from "chalk";
7
+ import path from "path";
8
+ import { logger } from "../lib/logger.js";
9
+ import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
+ import { EvoMapClient } from "../lib/evomap-client.js";
11
+ import { EvoMapManager } from "../lib/evomap-manager.js";
12
+ import {
13
+ ensureEvoMapFederationTables,
14
+ listFederatedHubs,
15
+ addFederatedHub,
16
+ syncGenes,
17
+ getPressureReport,
18
+ recombineGenes,
19
+ getLineage,
20
+ } from "../lib/evomap-federation.js";
21
+ import {
22
+ ensureEvoMapGovernanceTables,
23
+ registerOwnership,
24
+ traceOwnership,
25
+ createGovernanceProposal,
26
+ voteOnGovernanceProposal,
27
+ getGovernanceDashboard,
28
+ } from "../lib/evomap-governance.js";
29
+
30
+ export function registerEvoMapCommand(program) {
31
+ const evomap = program
32
+ .command("evomap")
33
+ .description("EvoMap — gene exchange protocol for agent capabilities");
34
+
35
+ // evomap search
36
+ evomap
37
+ .command("search <query>")
38
+ .description("Search for genes on the hub")
39
+ .option("-c, --category <cat>", "Filter by category")
40
+ .option("-n, --limit <n>", "Max results", "20")
41
+ .action(async (query, opts) => {
42
+ try {
43
+ const client = new EvoMapClient();
44
+ logger.info(`Searching for "${query}"...`);
45
+ const results = await client.search(query, {
46
+ category: opts.category,
47
+ limit: parseInt(opts.limit) || 20,
48
+ });
49
+
50
+ if (results.length === 0) {
51
+ logger.info("No genes found.");
52
+ return;
53
+ }
54
+
55
+ for (const gene of results) {
56
+ logger.log(
57
+ ` ${chalk.cyan(gene.name || gene.id)} v${gene.version || "?"} by ${gene.author || "unknown"}`,
58
+ );
59
+ if (gene.description) {
60
+ logger.log(` ${chalk.gray(gene.description.substring(0, 80))}`);
61
+ }
62
+ logger.log(
63
+ ` ${chalk.gray(`downloads: ${gene.downloads || 0} rating: ${gene.rating || "N/A"}`)}`,
64
+ );
65
+ }
66
+ logger.log(`\n${results.length} gene(s) found.`);
67
+ } catch (err) {
68
+ logger.error(`Search failed: ${err.message}`);
69
+ }
70
+ });
71
+
72
+ // evomap download
73
+ evomap
74
+ .command("download <geneId>")
75
+ .description("Download a gene from the hub")
76
+ .action(async (geneId) => {
77
+ try {
78
+ const client = new EvoMapClient();
79
+ const ctx = await bootstrap({ verbose: false }).catch(() => ({}));
80
+ const dataDir = process.env.CHAINLESSCHAIN_DATA_DIR || process.cwd();
81
+ const manager = new EvoMapManager({
82
+ genesDir: path.join(dataDir, "evomap", "genes"),
83
+ db: ctx.db || null,
84
+ });
85
+
86
+ logger.info(`Downloading gene ${geneId}...`);
87
+ const data = await client.download(geneId);
88
+ manager.saveGene(data.gene || data, data.content || "");
89
+ logger.success(`Gene ${geneId} installed.`);
90
+
91
+ await shutdown().catch(() => {});
92
+ } catch (err) {
93
+ logger.error(`Download failed: ${err.message}`);
94
+ }
95
+ });
96
+
97
+ // evomap publish
98
+ evomap
99
+ .command("publish")
100
+ .description("Publish a gene to the hub")
101
+ .requiredOption("--name <name>", "Gene name")
102
+ .option("--description <desc>", "Gene description")
103
+ .option("--category <cat>", "Gene category")
104
+ .option("--content <content>", "Gene content (or pipe stdin)")
105
+ .option("--author <author>", "Author name")
106
+ .action(async (opts) => {
107
+ try {
108
+ const client = new EvoMapClient();
109
+ const manager = new EvoMapManager({ genesDir: "" });
110
+
111
+ const gene = manager.packageGene({
112
+ name: opts.name,
113
+ description: opts.description,
114
+ category: opts.category,
115
+ content: opts.content || "",
116
+ author: opts.author,
117
+ });
118
+
119
+ logger.info(`Publishing gene "${opts.name}"...`);
120
+ await client.publish(gene);
121
+ logger.success(`Gene ${gene.id} published.`);
122
+ } catch (err) {
123
+ logger.error(`Publish failed: ${err.message}`);
124
+ }
125
+ });
126
+
127
+ // evomap list
128
+ evomap
129
+ .command("list")
130
+ .description("List locally installed genes")
131
+ .action(async () => {
132
+ try {
133
+ const ctx = await bootstrap({ verbose: false }).catch(() => ({}));
134
+ const dataDir = process.env.CHAINLESSCHAIN_DATA_DIR || process.cwd();
135
+ const manager = new EvoMapManager({
136
+ genesDir: path.join(dataDir, "evomap", "genes"),
137
+ db: ctx.db || null,
138
+ });
139
+ manager.initialize();
140
+
141
+ const genes = manager.listGenes();
142
+ if (genes.length === 0) {
143
+ logger.info(
144
+ "No genes installed. Use `evomap download <id>` to install.",
145
+ );
146
+ return;
147
+ }
148
+
149
+ for (const gene of genes) {
150
+ logger.log(
151
+ ` ${chalk.cyan(gene.name || gene.id)} v${gene.version || "?"} [${gene.category || "general"}]`,
152
+ );
153
+ if (gene.description) {
154
+ logger.log(` ${chalk.gray(gene.description.substring(0, 80))}`);
155
+ }
156
+ }
157
+ logger.log(`\n${genes.length} gene(s) installed.`);
158
+
159
+ await shutdown().catch(() => {});
160
+ } catch (err) {
161
+ logger.error(`List failed: ${err.message}`);
162
+ }
163
+ });
164
+
165
+ // evomap hubs
166
+ evomap
167
+ .command("hubs")
168
+ .description("List configured EvoMap hubs")
169
+ .action(async () => {
170
+ try {
171
+ const client = new EvoMapClient();
172
+ const hubs = await client.listHubs();
173
+ for (const hub of hubs) {
174
+ logger.log(
175
+ ` ${chalk.cyan(hub.url)} — ${hub.status || hub.name || "active"}`,
176
+ );
177
+ }
178
+ } catch (err) {
179
+ logger.error(`Hub list failed: ${err.message}`);
180
+ }
181
+ });
182
+
183
+ // ── Federation subcommands ──────────────────────────────────
184
+
185
+ const federation = evomap
186
+ .command("federation")
187
+ .description("Federated hub management and gene syncing");
188
+
189
+ federation
190
+ .command("list-hubs")
191
+ .description("List federated hubs")
192
+ .option("--status <status>", "Filter by status")
193
+ .option("--region <region>", "Filter by region")
194
+ .option("--json", "Output as JSON")
195
+ .action(async (options) => {
196
+ try {
197
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
198
+ if (!ctx.db) {
199
+ logger.error("Database not available");
200
+ process.exit(1);
201
+ }
202
+ const db = ctx.db.getDatabase();
203
+ ensureEvoMapFederationTables(db);
204
+
205
+ const hubs = listFederatedHubs(db, {
206
+ status: options.status,
207
+ region: options.region,
208
+ });
209
+ if (options.json) {
210
+ console.log(JSON.stringify(hubs, null, 2));
211
+ } else if (hubs.length === 0) {
212
+ logger.info(
213
+ "No federated hubs. Use `evomap federation add-hub` to add one.",
214
+ );
215
+ } else {
216
+ for (const h of hubs) {
217
+ logger.log(
218
+ ` ${chalk.cyan(h.id.slice(0, 8))} ${h.hubUrl} [${h.status}] region=${h.region} genes=${h.geneCount} trust=${h.trustScore.toFixed(2)}`,
219
+ );
220
+ }
221
+ }
222
+
223
+ await shutdown();
224
+ } catch (err) {
225
+ logger.error(`Failed: ${err.message}`);
226
+ process.exit(1);
227
+ }
228
+ });
229
+
230
+ federation
231
+ .command("add-hub <url>")
232
+ .description("Add a federated hub")
233
+ .option("-n, --name <name>", "Hub name")
234
+ .option("-r, --region <region>", "Hub region", "global")
235
+ .action(async (url, options) => {
236
+ try {
237
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
238
+ if (!ctx.db) {
239
+ logger.error("Database not available");
240
+ process.exit(1);
241
+ }
242
+ const db = ctx.db.getDatabase();
243
+ ensureEvoMapFederationTables(db);
244
+
245
+ const hub = addFederatedHub(db, url, options.name, options.region);
246
+ logger.success("Hub added");
247
+ logger.log(` ${chalk.bold("ID:")} ${chalk.cyan(hub.id)}`);
248
+ logger.log(` ${chalk.bold("URL:")} ${hub.hubUrl}`);
249
+ logger.log(` ${chalk.bold("Region:")} ${hub.region}`);
250
+
251
+ await shutdown();
252
+ } catch (err) {
253
+ logger.error(`Failed: ${err.message}`);
254
+ process.exit(1);
255
+ }
256
+ });
257
+
258
+ federation
259
+ .command("sync <hub-id>")
260
+ .description("Sync genes with a federated hub")
261
+ .option("--gene-ids <ids>", "Comma-separated gene IDs to sync")
262
+ .action(async (hubId, options) => {
263
+ try {
264
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
265
+ if (!ctx.db) {
266
+ logger.error("Database not available");
267
+ process.exit(1);
268
+ }
269
+ const db = ctx.db.getDatabase();
270
+ ensureEvoMapFederationTables(db);
271
+
272
+ const geneIds = options.geneIds
273
+ ? options.geneIds.split(",").map((s) => s.trim())
274
+ : [];
275
+ const result = syncGenes(db, hubId, geneIds);
276
+ logger.success(
277
+ `Synced ${result.synced} gene(s) with hub ${chalk.cyan(hubId.slice(0, 8))}`,
278
+ );
279
+
280
+ await shutdown();
281
+ } catch (err) {
282
+ logger.error(`Failed: ${err.message}`);
283
+ process.exit(1);
284
+ }
285
+ });
286
+
287
+ federation
288
+ .command("pressure")
289
+ .description("Show evolutionary pressure report")
290
+ .option("--json", "Output as JSON")
291
+ .action(async (options) => {
292
+ try {
293
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
294
+ if (!ctx.db) {
295
+ logger.error("Database not available");
296
+ process.exit(1);
297
+ }
298
+ const db = ctx.db.getDatabase();
299
+ ensureEvoMapFederationTables(db);
300
+
301
+ const report = getPressureReport();
302
+ if (options.json) {
303
+ console.log(JSON.stringify(report, null, 2));
304
+ } else {
305
+ logger.log(` ${chalk.bold("Total Genes:")} ${report.totalGenes}`);
306
+ logger.log(
307
+ ` ${chalk.bold("Avg Fitness:")} ${report.avgFitness.toFixed(3)}`,
308
+ );
309
+ logger.log(
310
+ ` ${chalk.bold("Max Generation:")} ${report.maxGeneration}`,
311
+ );
312
+ logger.log(` ${chalk.bold("Mutations:")} ${report.mutations}`);
313
+ logger.log(
314
+ ` ${chalk.bold("Recombinations:")} ${report.recombinations}`,
315
+ );
316
+ }
317
+
318
+ await shutdown();
319
+ } catch (err) {
320
+ logger.error(`Failed: ${err.message}`);
321
+ process.exit(1);
322
+ }
323
+ });
324
+
325
+ federation
326
+ .command("recombine <gene-id-1> <gene-id-2>")
327
+ .description("Recombine two genes to create offspring")
328
+ .action(async (geneId1, geneId2) => {
329
+ try {
330
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
331
+ if (!ctx.db) {
332
+ logger.error("Database not available");
333
+ process.exit(1);
334
+ }
335
+ const db = ctx.db.getDatabase();
336
+ ensureEvoMapFederationTables(db);
337
+
338
+ const entry = recombineGenes(db, geneId1, geneId2);
339
+ logger.success("Genes recombined");
340
+ logger.log(
341
+ ` ${chalk.bold("Child Gene:")} ${chalk.cyan(entry.geneId)}`,
342
+ );
343
+ logger.log(` ${chalk.bold("Parent 1:")} ${entry.parentGeneId}`);
344
+ logger.log(
345
+ ` ${chalk.bold("Parent 2:")} ${entry.recombinationSource}`,
346
+ );
347
+ logger.log(` ${chalk.bold("Generation:")} ${entry.generation}`);
348
+ logger.log(
349
+ ` ${chalk.bold("Fitness:")} ${entry.fitnessScore.toFixed(3)}`,
350
+ );
351
+
352
+ await shutdown();
353
+ } catch (err) {
354
+ logger.error(`Failed: ${err.message}`);
355
+ process.exit(1);
356
+ }
357
+ });
358
+
359
+ federation
360
+ .command("lineage <gene-id>")
361
+ .description("Show gene lineage and ancestry")
362
+ .option("--json", "Output as JSON")
363
+ .action(async (geneId, options) => {
364
+ try {
365
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
366
+ if (!ctx.db) {
367
+ logger.error("Database not available");
368
+ process.exit(1);
369
+ }
370
+ const db = ctx.db.getDatabase();
371
+ ensureEvoMapFederationTables(db);
372
+
373
+ const entries = getLineage(geneId);
374
+ if (options.json) {
375
+ console.log(JSON.stringify(entries, null, 2));
376
+ } else if (entries.length === 0) {
377
+ logger.info("No lineage found for this gene.");
378
+ } else {
379
+ for (const e of entries) {
380
+ logger.log(
381
+ ` ${chalk.cyan(e.id.slice(0, 8))} gene=${e.geneId.slice(0, 8)} gen=${e.generation} fitness=${e.fitnessScore.toFixed(2)} type=${e.mutationType}`,
382
+ );
383
+ }
384
+ }
385
+
386
+ await shutdown();
387
+ } catch (err) {
388
+ logger.error(`Failed: ${err.message}`);
389
+ process.exit(1);
390
+ }
391
+ });
392
+
393
+ // ── Governance subcommands ──────────────────────────────────
394
+
395
+ const gov = evomap
396
+ .command("gov")
397
+ .description("EvoMap governance — ownership, proposals, voting");
398
+
399
+ gov
400
+ .command("ownership-register <gene-id> <owner-did>")
401
+ .description("Register gene ownership")
402
+ .action(async (geneId, ownerDid) => {
403
+ try {
404
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
405
+ if (!ctx.db) {
406
+ logger.error("Database not available");
407
+ process.exit(1);
408
+ }
409
+ const db = ctx.db.getDatabase();
410
+ ensureEvoMapGovernanceTables(db);
411
+
412
+ const result = registerOwnership(db, geneId, ownerDid);
413
+ logger.success("Ownership registered");
414
+ logger.log(` ${chalk.bold("ID:")} ${chalk.cyan(result.id)}`);
415
+ logger.log(` ${chalk.bold("Gene:")} ${result.geneId}`);
416
+ logger.log(` ${chalk.bold("Owner:")} ${result.ownerDid}`);
417
+
418
+ await shutdown();
419
+ } catch (err) {
420
+ logger.error(`Failed: ${err.message}`);
421
+ process.exit(1);
422
+ }
423
+ });
424
+
425
+ gov
426
+ .command("ownership-trace <gene-id>")
427
+ .description("Trace gene ownership and contributions")
428
+ .option("--json", "Output as JSON")
429
+ .action(async (geneId, options) => {
430
+ try {
431
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
432
+ if (!ctx.db) {
433
+ logger.error("Database not available");
434
+ process.exit(1);
435
+ }
436
+ const db = ctx.db.getDatabase();
437
+ ensureEvoMapGovernanceTables(db);
438
+
439
+ const result = traceOwnership(geneId);
440
+ if (options.json) {
441
+ console.log(JSON.stringify(result, null, 2));
442
+ } else {
443
+ logger.log(` ${chalk.bold("Gene:")} ${result.geneId}`);
444
+ logger.log(
445
+ ` ${chalk.bold("Owner:")} ${result.owner || "N/A"}`,
446
+ );
447
+ logger.log(
448
+ ` ${chalk.bold("Contributors:")} ${result.contributors.join(", ") || "N/A"}`,
449
+ );
450
+ }
451
+
452
+ await shutdown();
453
+ } catch (err) {
454
+ logger.error(`Failed: ${err.message}`);
455
+ process.exit(1);
456
+ }
457
+ });
458
+
459
+ gov
460
+ .command("propose <title>")
461
+ .description("Create a governance proposal")
462
+ .option("-d, --description <text>", "Proposal description")
463
+ .option("-p, --proposer <did>", "Proposer DID", "cli-user")
464
+ .action(async (title, options) => {
465
+ try {
466
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
467
+ if (!ctx.db) {
468
+ logger.error("Database not available");
469
+ process.exit(1);
470
+ }
471
+ const db = ctx.db.getDatabase();
472
+ ensureEvoMapGovernanceTables(db);
473
+
474
+ const result = createGovernanceProposal(
475
+ db,
476
+ title,
477
+ options.description,
478
+ options.proposer,
479
+ );
480
+ logger.success("Proposal created");
481
+ logger.log(` ${chalk.bold("ID:")} ${chalk.cyan(result.id)}`);
482
+ logger.log(` ${chalk.bold("Title:")} ${result.title}`);
483
+ logger.log(` ${chalk.bold("Status:")} ${result.status}`);
484
+
485
+ await shutdown();
486
+ } catch (err) {
487
+ logger.error(`Failed: ${err.message}`);
488
+ process.exit(1);
489
+ }
490
+ });
491
+
492
+ gov
493
+ .command("vote <proposal-id> <direction>")
494
+ .description('Vote on a governance proposal ("for" or "against")')
495
+ .option("-v, --voter <did>", "Voter DID", "cli-user")
496
+ .action(async (proposalId, direction, options) => {
497
+ try {
498
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
499
+ if (!ctx.db) {
500
+ logger.error("Database not available");
501
+ process.exit(1);
502
+ }
503
+ const db = ctx.db.getDatabase();
504
+ ensureEvoMapGovernanceTables(db);
505
+
506
+ const result = voteOnGovernanceProposal(
507
+ db,
508
+ proposalId,
509
+ options.voter,
510
+ direction,
511
+ );
512
+ logger.success("Vote recorded");
513
+ logger.log(` ${chalk.bold("Proposal:")} ${result.proposalId}`);
514
+ logger.log(` ${chalk.bold("Direction:")} ${result.vote}`);
515
+ logger.log(` ${chalk.bold("Total Votes:")} ${result.totalVotes}`);
516
+ logger.log(` ${chalk.bold("Status:")} ${result.status}`);
517
+
518
+ await shutdown();
519
+ } catch (err) {
520
+ logger.error(`Failed: ${err.message}`);
521
+ process.exit(1);
522
+ }
523
+ });
524
+
525
+ gov
526
+ .command("dashboard")
527
+ .description("Show governance dashboard")
528
+ .option("--json", "Output as JSON")
529
+ .action(async (options) => {
530
+ try {
531
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
532
+ if (!ctx.db) {
533
+ logger.error("Database not available");
534
+ process.exit(1);
535
+ }
536
+ const db = ctx.db.getDatabase();
537
+ ensureEvoMapGovernanceTables(db);
538
+
539
+ const result = getGovernanceDashboard();
540
+ if (options.json) {
541
+ console.log(JSON.stringify(result, null, 2));
542
+ } else {
543
+ logger.log(
544
+ ` ${chalk.bold("Total Proposals:")} ${result.totalProposals}`,
545
+ );
546
+ logger.log(` ${chalk.bold("Active:")} ${result.active}`);
547
+ logger.log(` ${chalk.bold("Passed:")} ${result.passed}`);
548
+ logger.log(` ${chalk.bold("Rejected:")} ${result.rejected}`);
549
+ logger.log(` ${chalk.bold("Executed:")} ${result.executed}`);
550
+ }
551
+
552
+ await shutdown();
553
+ } catch (err) {
554
+ logger.error(`Failed: ${err.message}`);
555
+ process.exit(1);
556
+ }
557
+ });
558
+ }