chainlesschain 0.51.0 → 0.81.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/a2a.js +380 -0
- package/src/commands/agent-network.js +785 -0
- package/src/commands/automation.js +654 -0
- package/src/commands/bi.js +348 -0
- package/src/commands/crosschain.js +218 -0
- package/src/commands/dao.js +565 -0
- package/src/commands/did-v2.js +620 -0
- package/src/commands/dlp.js +341 -0
- package/src/commands/economy.js +578 -0
- package/src/commands/evolution.js +391 -0
- package/src/commands/evomap.js +394 -0
- package/src/commands/federation.js +283 -0
- package/src/commands/hmemory.js +442 -0
- package/src/commands/inference.js +318 -0
- package/src/commands/lowcode.js +356 -0
- package/src/commands/marketplace.js +256 -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/privacy.js +321 -0
- package/src/commands/reputation.js +261 -0
- package/src/commands/sandbox.js +401 -0
- package/src/commands/siem.js +246 -0
- package/src/commands/sla.js +259 -0
- package/src/commands/social.js +311 -0
- package/src/commands/sso.js +798 -0
- package/src/commands/stress.js +230 -0
- package/src/commands/terraform.js +245 -0
- package/src/commands/workflow.js +320 -0
- package/src/commands/zkp.js +562 -1
- package/src/index.js +21 -0
- package/src/lib/a2a-protocol.js +451 -0
- package/src/lib/agent-economy.js +479 -0
- package/src/lib/agent-network.js +1121 -0
- package/src/lib/app-builder.js +239 -0
- package/src/lib/automation-engine.js +948 -0
- package/src/lib/bi-engine.js +338 -0
- package/src/lib/cross-chain.js +345 -0
- package/src/lib/dao-governance.js +569 -0
- package/src/lib/did-v2-manager.js +1127 -0
- package/src/lib/dlp-engine.js +389 -0
- package/src/lib/evolution-system.js +453 -0
- package/src/lib/evomap-federation.js +177 -0
- package/src/lib/evomap-governance.js +276 -0
- package/src/lib/federation-hardening.js +259 -0
- package/src/lib/hierarchical-memory.js +481 -0
- package/src/lib/inference-network.js +330 -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/privacy-computing.js +427 -0
- package/src/lib/reputation-optimizer.js +299 -0
- package/src/lib/sandbox-v2.js +306 -0
- package/src/lib/siem-exporter.js +333 -0
- package/src/lib/skill-marketplace.js +325 -0
- package/src/lib/sla-manager.js +275 -0
- package/src/lib/social-graph-analytics.js +707 -0
- package/src/lib/sso-manager.js +841 -0
- package/src/lib/stress-tester.js +330 -0
- package/src/lib/terraform-manager.js +363 -0
- package/src/lib/workflow-engine.js +454 -1
- package/src/lib/zkp-engine.js +523 -20
- package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
package/src/commands/hmemory.js
CHANGED
|
@@ -16,6 +16,23 @@ import {
|
|
|
16
16
|
getMemoryStats,
|
|
17
17
|
shareMemory,
|
|
18
18
|
pruneMemory,
|
|
19
|
+
// Phase 83 V2
|
|
20
|
+
MEMORY_LAYER,
|
|
21
|
+
MEMORY_TYPE,
|
|
22
|
+
CONSOLIDATION_STATUS,
|
|
23
|
+
SHARE_PERMISSION,
|
|
24
|
+
attachMetadata,
|
|
25
|
+
promoteMemoryV2,
|
|
26
|
+
demoteMemoryV2,
|
|
27
|
+
shareMemoryV2,
|
|
28
|
+
revokeShare,
|
|
29
|
+
listShares,
|
|
30
|
+
searchEpisodicV2,
|
|
31
|
+
searchSemanticV2,
|
|
32
|
+
consolidateV2,
|
|
33
|
+
listConsolidations,
|
|
34
|
+
pruneV2,
|
|
35
|
+
getStatsV2,
|
|
19
36
|
} from "../lib/hierarchical-memory.js";
|
|
20
37
|
|
|
21
38
|
export function registerHmemoryCommand(program) {
|
|
@@ -270,4 +287,429 @@ export function registerHmemoryCommand(program) {
|
|
|
270
287
|
process.exit(1);
|
|
271
288
|
}
|
|
272
289
|
});
|
|
290
|
+
|
|
291
|
+
// ═════════════════════════════════════════════════════════════
|
|
292
|
+
// Phase 83 — Hierarchical Memory 2.0 subcommands
|
|
293
|
+
// ═════════════════════════════════════════════════════════════
|
|
294
|
+
|
|
295
|
+
// hmemory layers
|
|
296
|
+
hmemory
|
|
297
|
+
.command("layers")
|
|
298
|
+
.description("List MEMORY_LAYER enum values")
|
|
299
|
+
.option("--json", "Output as JSON")
|
|
300
|
+
.action((options) => {
|
|
301
|
+
const layers = Object.values(MEMORY_LAYER);
|
|
302
|
+
if (options.json) console.log(JSON.stringify(layers, null, 2));
|
|
303
|
+
else for (const l of layers) logger.log(` ${chalk.cyan(l)}`);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// hmemory types
|
|
307
|
+
hmemory
|
|
308
|
+
.command("types")
|
|
309
|
+
.description("List MEMORY_TYPE enum values")
|
|
310
|
+
.option("--json", "Output as JSON")
|
|
311
|
+
.action((options) => {
|
|
312
|
+
const types = Object.values(MEMORY_TYPE);
|
|
313
|
+
if (options.json) console.log(JSON.stringify(types, null, 2));
|
|
314
|
+
else for (const t of types) logger.log(` ${chalk.cyan(t)}`);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// hmemory statuses
|
|
318
|
+
hmemory
|
|
319
|
+
.command("statuses")
|
|
320
|
+
.description("List CONSOLIDATION_STATUS enum values")
|
|
321
|
+
.option("--json", "Output as JSON")
|
|
322
|
+
.action((options) => {
|
|
323
|
+
const sts = Object.values(CONSOLIDATION_STATUS);
|
|
324
|
+
if (options.json) console.log(JSON.stringify(sts, null, 2));
|
|
325
|
+
else for (const s of sts) logger.log(` ${chalk.cyan(s)}`);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// hmemory permissions
|
|
329
|
+
hmemory
|
|
330
|
+
.command("permissions")
|
|
331
|
+
.description("List SHARE_PERMISSION enum values")
|
|
332
|
+
.option("--json", "Output as JSON")
|
|
333
|
+
.action((options) => {
|
|
334
|
+
const ps = Object.values(SHARE_PERMISSION);
|
|
335
|
+
if (options.json) console.log(JSON.stringify(ps, null, 2));
|
|
336
|
+
else for (const p of ps) logger.log(` ${chalk.cyan(p)}`);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// hmemory attach-metadata <id>
|
|
340
|
+
hmemory
|
|
341
|
+
.command("attach-metadata <id>")
|
|
342
|
+
.description("Attach V2 metadata (scene/context/concepts) to a memory")
|
|
343
|
+
.option("--scene <s>", "Scene tag")
|
|
344
|
+
.option("--context <c>", "Context description")
|
|
345
|
+
.option("--concepts <c1,c2>", "Comma-separated concept tags")
|
|
346
|
+
.option("--agent-id <id>", "Associated agent ID")
|
|
347
|
+
.option("--json", "Output as JSON")
|
|
348
|
+
.action(async (id, options) => {
|
|
349
|
+
try {
|
|
350
|
+
await bootstrap({ verbose: program.opts().verbose });
|
|
351
|
+
const meta = {};
|
|
352
|
+
if (options.scene) meta.scene = options.scene;
|
|
353
|
+
if (options.context) meta.context = options.context;
|
|
354
|
+
if (options.concepts)
|
|
355
|
+
meta.concepts = options.concepts
|
|
356
|
+
.split(",")
|
|
357
|
+
.map((s) => s.trim())
|
|
358
|
+
.filter(Boolean);
|
|
359
|
+
if (options.agentId) meta.agentId = options.agentId;
|
|
360
|
+
|
|
361
|
+
const result = attachMetadata(id, meta);
|
|
362
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
363
|
+
else
|
|
364
|
+
logger.success(
|
|
365
|
+
`Metadata attached to ${chalk.gray(id.slice(0, 16))}: ${chalk.cyan(Object.keys(meta).join(","))}`,
|
|
366
|
+
);
|
|
367
|
+
await shutdown();
|
|
368
|
+
} catch (err) {
|
|
369
|
+
logger.error(`Failed: ${err.message}`);
|
|
370
|
+
process.exit(1);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// hmemory promote-v2 <id>
|
|
375
|
+
hmemory
|
|
376
|
+
.command("promote-v2 <id>")
|
|
377
|
+
.description("Promote memory one layer up (working→short-term→long-term)")
|
|
378
|
+
.option("--json", "Output as JSON")
|
|
379
|
+
.action(async (id, options) => {
|
|
380
|
+
try {
|
|
381
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
382
|
+
const db = ctx.db.getDatabase();
|
|
383
|
+
const result = promoteMemoryV2(db, id);
|
|
384
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
385
|
+
else
|
|
386
|
+
logger.success(
|
|
387
|
+
`Promoted: ${chalk.gray(id.slice(0, 16))} ${chalk.yellow(result.from)} → ${chalk.cyan(result.to)}`,
|
|
388
|
+
);
|
|
389
|
+
await shutdown();
|
|
390
|
+
} catch (err) {
|
|
391
|
+
logger.error(`Failed: ${err.message}`);
|
|
392
|
+
process.exit(1);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// hmemory demote-v2 <id>
|
|
397
|
+
hmemory
|
|
398
|
+
.command("demote-v2 <id>")
|
|
399
|
+
.description("Demote memory one layer down (short-term → working)")
|
|
400
|
+
.option("--json", "Output as JSON")
|
|
401
|
+
.action(async (id, options) => {
|
|
402
|
+
try {
|
|
403
|
+
await bootstrap({ verbose: program.opts().verbose });
|
|
404
|
+
const result = demoteMemoryV2(id);
|
|
405
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
406
|
+
else
|
|
407
|
+
logger.success(
|
|
408
|
+
`Demoted: ${chalk.gray(id.slice(0, 16))} ${chalk.yellow(result.from)} → ${chalk.cyan(result.to)}`,
|
|
409
|
+
);
|
|
410
|
+
await shutdown();
|
|
411
|
+
} catch (err) {
|
|
412
|
+
logger.error(`Failed: ${err.message}`);
|
|
413
|
+
process.exit(1);
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// hmemory share-v2 <id> <target>
|
|
418
|
+
hmemory
|
|
419
|
+
.command("share-v2 <id> <target>")
|
|
420
|
+
.description("Share a memory with permissions (read,copy,modify)")
|
|
421
|
+
.option("--source <agent>", "Source agent ID", "local")
|
|
422
|
+
.option("--permissions <p1,p2>", "Comma-separated perms", "read")
|
|
423
|
+
.option("--json", "Output as JSON")
|
|
424
|
+
.action(async (id, target, options) => {
|
|
425
|
+
try {
|
|
426
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
427
|
+
const db = ctx.db.getDatabase();
|
|
428
|
+
const perms = options.permissions
|
|
429
|
+
.split(",")
|
|
430
|
+
.map((s) => s.trim())
|
|
431
|
+
.filter(Boolean);
|
|
432
|
+
const record = shareMemoryV2(db, {
|
|
433
|
+
memoryId: id,
|
|
434
|
+
sourceAgent: options.source,
|
|
435
|
+
targetAgent: target,
|
|
436
|
+
permissions: perms,
|
|
437
|
+
});
|
|
438
|
+
if (options.json) console.log(JSON.stringify(record, null, 2));
|
|
439
|
+
else
|
|
440
|
+
logger.success(
|
|
441
|
+
`Shared ${chalk.gray(id.slice(0, 16))} → ${chalk.cyan(target)} [${perms.join(",")}]`,
|
|
442
|
+
);
|
|
443
|
+
await shutdown();
|
|
444
|
+
} catch (err) {
|
|
445
|
+
logger.error(`Failed: ${err.message}`);
|
|
446
|
+
process.exit(1);
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
// hmemory revoke-share <shareId>
|
|
451
|
+
hmemory
|
|
452
|
+
.command("revoke-share <shareId>")
|
|
453
|
+
.description("Revoke a sharing record")
|
|
454
|
+
.option("--json", "Output as JSON")
|
|
455
|
+
.action(async (shareId, options) => {
|
|
456
|
+
try {
|
|
457
|
+
await bootstrap({ verbose: program.opts().verbose });
|
|
458
|
+
const record = revokeShare(shareId);
|
|
459
|
+
if (options.json) console.log(JSON.stringify(record, null, 2));
|
|
460
|
+
else
|
|
461
|
+
logger.success(
|
|
462
|
+
`Revoked ${chalk.gray(shareId.slice(0, 20))} at ${record.revokedAt}`,
|
|
463
|
+
);
|
|
464
|
+
await shutdown();
|
|
465
|
+
} catch (err) {
|
|
466
|
+
logger.error(`Failed: ${err.message}`);
|
|
467
|
+
process.exit(1);
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
// hmemory shares
|
|
472
|
+
hmemory
|
|
473
|
+
.command("shares")
|
|
474
|
+
.description("List V2 sharing records")
|
|
475
|
+
.option("--memory-id <id>", "Filter by memoryId")
|
|
476
|
+
.option("--target <agent>", "Filter by targetAgent")
|
|
477
|
+
.option("--active-only", "Only active (non-revoked) shares")
|
|
478
|
+
.option("--json", "Output as JSON")
|
|
479
|
+
.action(async (options) => {
|
|
480
|
+
try {
|
|
481
|
+
await bootstrap({ verbose: program.opts().verbose });
|
|
482
|
+
const shares = listShares({
|
|
483
|
+
memoryId: options.memoryId,
|
|
484
|
+
targetAgent: options.target,
|
|
485
|
+
activeOnly: options.activeOnly,
|
|
486
|
+
});
|
|
487
|
+
if (options.json) console.log(JSON.stringify(shares, null, 2));
|
|
488
|
+
else if (shares.length === 0) logger.info("No shares matching filters");
|
|
489
|
+
else {
|
|
490
|
+
for (const s of shares) {
|
|
491
|
+
const status = s.revokedAt
|
|
492
|
+
? chalk.red("revoked")
|
|
493
|
+
: chalk.green("active");
|
|
494
|
+
logger.log(
|
|
495
|
+
` ${chalk.gray(s.id.slice(0, 16))} ${chalk.cyan(s.memoryId)} → ${s.targetAgent} [${s.permissions.join(",")}] (${status})`,
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
await shutdown();
|
|
500
|
+
} catch (err) {
|
|
501
|
+
logger.error(`Failed: ${err.message}`);
|
|
502
|
+
process.exit(1);
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
// hmemory search-episodic-v2
|
|
507
|
+
hmemory
|
|
508
|
+
.command("search-episodic-v2 [query]")
|
|
509
|
+
.description("Search episodic memories with time/scene/context filters")
|
|
510
|
+
.option("--from <iso>", "Time range start (ISO)")
|
|
511
|
+
.option("--to <iso>", "Time range end (ISO)")
|
|
512
|
+
.option("--scene <s>", "Filter by scene metadata")
|
|
513
|
+
.option("--context <c>", "Filter by context substring")
|
|
514
|
+
.option("-n, --limit <n>", "Max results", "20")
|
|
515
|
+
.option("--json", "Output as JSON")
|
|
516
|
+
.action(async (query, options) => {
|
|
517
|
+
try {
|
|
518
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
519
|
+
const db = ctx.db.getDatabase();
|
|
520
|
+
const timeRange =
|
|
521
|
+
options.from || options.to
|
|
522
|
+
? { from: options.from, to: options.to }
|
|
523
|
+
: null;
|
|
524
|
+
const results = searchEpisodicV2(db, {
|
|
525
|
+
query,
|
|
526
|
+
timeRange,
|
|
527
|
+
scene: options.scene,
|
|
528
|
+
context: options.context,
|
|
529
|
+
limit: parseInt(options.limit) || 20,
|
|
530
|
+
});
|
|
531
|
+
if (options.json) console.log(JSON.stringify(results, null, 2));
|
|
532
|
+
else if (results.length === 0) logger.info("No episodic matches");
|
|
533
|
+
else {
|
|
534
|
+
logger.log(chalk.bold(`Episodic V2 results (${results.length}):\n`));
|
|
535
|
+
for (const r of results) {
|
|
536
|
+
const meta = r.metadata
|
|
537
|
+
? ` {scene=${r.metadata.scene || "-"}}`
|
|
538
|
+
: "";
|
|
539
|
+
logger.log(
|
|
540
|
+
` ${chalk.gray(r.id.slice(0, 16))} [${chalk.cyan(r.layer)}]${meta}`,
|
|
541
|
+
);
|
|
542
|
+
logger.log(` ${chalk.white(r.content.slice(0, 100))}`);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
await shutdown();
|
|
546
|
+
} catch (err) {
|
|
547
|
+
logger.error(`Failed: ${err.message}`);
|
|
548
|
+
process.exit(1);
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
// hmemory search-semantic-v2
|
|
553
|
+
hmemory
|
|
554
|
+
.command("search-semantic-v2 [query]")
|
|
555
|
+
.description("Search semantic memories with concept similarity")
|
|
556
|
+
.option("--concepts <c1,c2>", "Comma-separated concept tags")
|
|
557
|
+
.option("--similarity <n>", "Similarity threshold 0..1", "0")
|
|
558
|
+
.option("-n, --limit <n>", "Max results", "20")
|
|
559
|
+
.option("--json", "Output as JSON")
|
|
560
|
+
.action(async (query, options) => {
|
|
561
|
+
try {
|
|
562
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
563
|
+
const db = ctx.db.getDatabase();
|
|
564
|
+
const concepts = options.concepts
|
|
565
|
+
? options.concepts
|
|
566
|
+
.split(",")
|
|
567
|
+
.map((s) => s.trim())
|
|
568
|
+
.filter(Boolean)
|
|
569
|
+
: [];
|
|
570
|
+
const results = searchSemanticV2(db, {
|
|
571
|
+
query,
|
|
572
|
+
concepts,
|
|
573
|
+
similarityThreshold: parseFloat(options.similarity) || 0,
|
|
574
|
+
limit: parseInt(options.limit) || 20,
|
|
575
|
+
});
|
|
576
|
+
if (options.json) console.log(JSON.stringify(results, null, 2));
|
|
577
|
+
else if (results.length === 0) logger.info("No semantic matches");
|
|
578
|
+
else {
|
|
579
|
+
logger.log(chalk.bold(`Semantic V2 results (${results.length}):\n`));
|
|
580
|
+
for (const r of results) {
|
|
581
|
+
const sim = (r.similarity * 100).toFixed(0);
|
|
582
|
+
logger.log(
|
|
583
|
+
` ${chalk.gray(r.id.slice(0, 16))} [${chalk.cyan(r.layer)}] sim=${chalk.yellow(sim + "%")}`,
|
|
584
|
+
);
|
|
585
|
+
logger.log(` ${chalk.white(r.content.slice(0, 100))}`);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
await shutdown();
|
|
589
|
+
} catch (err) {
|
|
590
|
+
logger.error(`Failed: ${err.message}`);
|
|
591
|
+
process.exit(1);
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
// hmemory consolidate-v2
|
|
596
|
+
hmemory
|
|
597
|
+
.command("consolidate-v2")
|
|
598
|
+
.description("Run V2 consolidation with status tracking")
|
|
599
|
+
.option("--extract-patterns", "Snapshot patterns from short-term")
|
|
600
|
+
.option("--json", "Output as JSON")
|
|
601
|
+
.action(async (options) => {
|
|
602
|
+
try {
|
|
603
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
604
|
+
const db = ctx.db.getDatabase();
|
|
605
|
+
const record = consolidateV2(db, {
|
|
606
|
+
extractPatterns: options.extractPatterns,
|
|
607
|
+
});
|
|
608
|
+
if (options.json) console.log(JSON.stringify(record, null, 2));
|
|
609
|
+
else {
|
|
610
|
+
const color = record.status === "completed" ? chalk.green : chalk.red;
|
|
611
|
+
logger.log(
|
|
612
|
+
`${color(record.status)} — promoted=${record.promoted} forgotten=${record.forgotten} patterns=${record.patterns.length}`,
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
await shutdown();
|
|
616
|
+
} catch (err) {
|
|
617
|
+
logger.error(`Failed: ${err.message}`);
|
|
618
|
+
process.exit(1);
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
// hmemory consolidations
|
|
623
|
+
hmemory
|
|
624
|
+
.command("consolidations")
|
|
625
|
+
.description("List V2 consolidation run history")
|
|
626
|
+
.option("--status <s>", "Filter by status")
|
|
627
|
+
.option("--json", "Output as JSON")
|
|
628
|
+
.action(async (options) => {
|
|
629
|
+
try {
|
|
630
|
+
await bootstrap({ verbose: program.opts().verbose });
|
|
631
|
+
const records = listConsolidations({ status: options.status });
|
|
632
|
+
if (options.json) console.log(JSON.stringify(records, null, 2));
|
|
633
|
+
else if (records.length === 0) logger.info("No consolidation history");
|
|
634
|
+
else
|
|
635
|
+
for (const r of records) {
|
|
636
|
+
logger.log(
|
|
637
|
+
` ${chalk.gray(r.id.slice(0, 20))} [${chalk.cyan(r.status)}] promoted=${r.promoted} forgotten=${r.forgotten}`,
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
await shutdown();
|
|
641
|
+
} catch (err) {
|
|
642
|
+
logger.error(`Failed: ${err.message}`);
|
|
643
|
+
process.exit(1);
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
// hmemory prune-v2
|
|
648
|
+
hmemory
|
|
649
|
+
.command("prune-v2")
|
|
650
|
+
.description("Layer-scoped prune with custom threshold")
|
|
651
|
+
.option("--layer <l>", "working | short-term | long-term")
|
|
652
|
+
.option("--max-age <hours>", "Max age hours for long-term", "720")
|
|
653
|
+
.option("--threshold <n>", "Retention threshold override 0..1")
|
|
654
|
+
.option("--json", "Output as JSON")
|
|
655
|
+
.action(async (options) => {
|
|
656
|
+
try {
|
|
657
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
658
|
+
const db = ctx.db.getDatabase();
|
|
659
|
+
const result = pruneV2(db, {
|
|
660
|
+
layer: options.layer,
|
|
661
|
+
maxAge: parseFloat(options.maxAge) || 720,
|
|
662
|
+
threshold:
|
|
663
|
+
options.threshold !== undefined
|
|
664
|
+
? parseFloat(options.threshold)
|
|
665
|
+
: undefined,
|
|
666
|
+
});
|
|
667
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
668
|
+
else
|
|
669
|
+
logger.success(
|
|
670
|
+
`Pruned ${chalk.red(result.pruned)} from layer=${chalk.cyan(result.layer)}`,
|
|
671
|
+
);
|
|
672
|
+
await shutdown();
|
|
673
|
+
} catch (err) {
|
|
674
|
+
logger.error(`Failed: ${err.message}`);
|
|
675
|
+
process.exit(1);
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
// hmemory stats-v2
|
|
680
|
+
hmemory
|
|
681
|
+
.command("stats-v2")
|
|
682
|
+
.description("Extended V2 stats with per-layer + consolidation + shares")
|
|
683
|
+
.option("--json", "Output as JSON")
|
|
684
|
+
.action(async (options) => {
|
|
685
|
+
try {
|
|
686
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
687
|
+
const db = ctx.db.getDatabase();
|
|
688
|
+
const stats = getStatsV2(db);
|
|
689
|
+
if (options.json) console.log(JSON.stringify(stats, null, 2));
|
|
690
|
+
else {
|
|
691
|
+
logger.log(chalk.bold("Hierarchical Memory 2.0 Stats:\n"));
|
|
692
|
+
logger.log(` Per-layer:`);
|
|
693
|
+
for (const [l, n] of Object.entries(stats.perLayer)) {
|
|
694
|
+
logger.log(` ${chalk.cyan(l.padEnd(12))} ${chalk.yellow(n)}`);
|
|
695
|
+
}
|
|
696
|
+
logger.log(` Consolidations: total=${stats.consolidation.total}`);
|
|
697
|
+
for (const [k, v] of Object.entries(
|
|
698
|
+
stats.consolidation.byStatus || {},
|
|
699
|
+
)) {
|
|
700
|
+
logger.log(` ${chalk.cyan(k.padEnd(12))} ${chalk.yellow(v)}`);
|
|
701
|
+
}
|
|
702
|
+
logger.log(
|
|
703
|
+
` Shares: total=${stats.shares.total} active=${chalk.green(stats.shares.active)} revoked=${chalk.red(stats.shares.revoked)}`,
|
|
704
|
+
);
|
|
705
|
+
logger.log(
|
|
706
|
+
` Metadata entries: ${chalk.yellow(stats.metadataEntries)}`,
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
await shutdown();
|
|
710
|
+
} catch (err) {
|
|
711
|
+
logger.error(`Failed: ${err.message}`);
|
|
712
|
+
process.exit(1);
|
|
713
|
+
}
|
|
714
|
+
});
|
|
273
715
|
}
|