@shadowforge0/aquifer-memory 1.8.1 → 1.9.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.
- package/.env.example +1 -0
- package/README.md +82 -26
- package/README_CN.md +33 -23
- package/README_TW.md +25 -24
- package/aquifer.config.example.json +2 -1
- package/consumers/cli.js +587 -33
- package/consumers/codex-active-checkpoint.js +3 -1
- package/consumers/codex-current-memory.js +10 -6
- package/consumers/codex.js +6 -3
- package/consumers/default/daily-entries.js +2 -2
- package/consumers/default/index.js +40 -30
- package/consumers/default/prompts/summary.js +2 -2
- package/consumers/mcp.js +56 -46
- package/consumers/openclaw-ext/index.js +65 -7
- package/consumers/openclaw-ext/openclaw.plugin.json +1 -1
- package/consumers/openclaw-ext/package.json +1 -1
- package/consumers/openclaw-install.js +326 -0
- package/consumers/openclaw-plugin.js +105 -24
- package/consumers/shared/compat-recall.js +101 -0
- package/consumers/shared/config.js +2 -0
- package/consumers/shared/openclaw-product-tools.js +130 -0
- package/consumers/shared/recall-format.js +2 -2
- package/core/aquifer.js +553 -41
- package/core/backends/local.js +169 -1
- package/core/doctor.js +924 -0
- package/core/finalization-inspector.js +164 -0
- package/core/finalization-review.js +88 -42
- package/core/interface.js +629 -0
- package/core/mcp-manifest.js +11 -3
- package/core/memory-bootstrap.js +25 -27
- package/core/memory-consolidation.js +564 -42
- package/core/memory-explain.js +593 -0
- package/core/memory-promotion.js +392 -55
- package/core/memory-recall.js +75 -71
- package/core/memory-records.js +107 -108
- package/core/memory-review.js +891 -0
- package/core/memory-serving.js +61 -4
- package/core/memory-type-policy.js +298 -0
- package/core/operator-observability.js +249 -0
- package/core/postgres-migrations.js +22 -0
- package/core/session-checkpoint-producer.js +3 -1
- package/core/session-checkpoints.js +1 -1
- package/core/session-finalization.js +78 -3
- package/core/storage.js +124 -8
- package/docs/getting-started.md +50 -4
- package/docs/setup.md +163 -24
- package/package.json +5 -4
- package/schema/004-completion.sql +4 -4
- package/schema/010-v1-finalization-review.sql +72 -0
- package/schema/019-v1-memory-review-resolutions.sql +53 -0
- package/schema/020-v1-assistant-shaping-memory.sql +30 -0
- package/scripts/backfill-canonical-key.js +1 -1
- package/scripts/codex-checkpoint-commands.js +28 -0
- package/scripts/codex-checkpoint-runtime.js +109 -0
- package/scripts/codex-recovery.js +16 -4
- package/scripts/diagnose-fts-zh.js +1 -1
- package/scripts/extract-insights-from-recent-sessions.js +4 -4
package/consumers/cli.js
CHANGED
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
* aquifer migrate Run database migrations
|
|
10
10
|
* aquifer recall <query> [options] Search sessions
|
|
11
11
|
* aquifer backfill [options] Enrich pending sessions
|
|
12
|
-
* aquifer
|
|
12
|
+
* aquifer backlog [options] Explain saved-content preparation work
|
|
13
|
+
* aquifer stats [options] Check memory readiness and diagnostics
|
|
13
14
|
* aquifer backend-info [--json] Show selected backend capabilities
|
|
15
|
+
* aquifer install-openclaw Install/update OpenClaw MCP + extension wiring
|
|
16
|
+
* aquifer finalization ... Inspect read-only finalization ledger
|
|
14
17
|
* aquifer export [options] Export sessions
|
|
15
18
|
* aquifer operator ... Run operator-safe consolidation jobs
|
|
16
19
|
* aquifer mcp Start MCP server
|
|
@@ -21,12 +24,13 @@ const { createAquiferFromConfig } = require('./shared/factory');
|
|
|
21
24
|
const { loadConfig } = require('./shared/config');
|
|
22
25
|
const { formatRecallResults } = require('./shared/recall-format');
|
|
23
26
|
const { backendCapabilities } = require('../core/backends/capabilities');
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
const { summarizeFinalizationListRow } = require('../core/finalization-inspector');
|
|
28
|
+
const {
|
|
29
|
+
buildBacklogEnvelope,
|
|
30
|
+
buildStatsEnvelope,
|
|
31
|
+
formatMemoryStatsInterface,
|
|
32
|
+
formatPendingWorkInterface,
|
|
33
|
+
} = require('../core/interface');
|
|
30
34
|
|
|
31
35
|
function quoteIdentifier(identifier) {
|
|
32
36
|
if (!/^[a-zA-Z_]\w{0,62}$/.test(identifier)) {
|
|
@@ -42,6 +46,12 @@ function parsePositiveInt(value, fallback) {
|
|
|
42
46
|
return Math.max(1, parsed);
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
function printTextBlock(text) {
|
|
50
|
+
for (const line of String(text).split(/\r?\n/)) {
|
|
51
|
+
console.log(line);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
function parseScopePath(value) {
|
|
46
56
|
if (!value) return undefined;
|
|
47
57
|
const parts = String(value).split(',').map(s => s.trim()).filter(Boolean);
|
|
@@ -177,12 +187,16 @@ function parseArgs(argv) {
|
|
|
177
187
|
// Flags that take a value (not boolean)
|
|
178
188
|
const VALUE_FLAGS = new Set([
|
|
179
189
|
'limit', 'agent-id', 'source', 'date-from', 'date-to', 'output', 'format', 'config', 'status',
|
|
190
|
+
'plan', 'action',
|
|
180
191
|
'concurrency', 'entities', 'entity-mode', 'mode', 'session-id', 'memory-id', 'canonical-key',
|
|
181
192
|
'verdict', 'feedback-type', 'note', 'db', 'since', 'min-messages', 'lookback-days', 'max-chars',
|
|
182
193
|
'out', 'active-scope-key', 'active-scope-path', 'cadence', 'period-start', 'period-end',
|
|
183
194
|
'policy-version', 'worker-id', 'apply-token', 'claim-lease-seconds', 'snapshot-as-of',
|
|
184
195
|
'scope-id', 'scope-key', 'scope-keys', 'scope-kind', 'context-key', 'topic-key', 'authority', 'input',
|
|
185
196
|
'synthesis-summary', 'synthesis-summary-file', 'min-finalizations', 'checkpoint-key',
|
|
197
|
+
'openclaw-home', 'id', 'transcript-hash', 'phase', 'host', 'run-id', 'kind', 'query',
|
|
198
|
+
'memory-type', 'visibility', 'as-of', 'resolution', 'reason', 'actor-kind', 'actor-id',
|
|
199
|
+
'defer-until', 'expected-latest-issue-feedback-id', 'expected-latest-issue-feedback-at',
|
|
186
200
|
]);
|
|
187
201
|
for (let i = 0; i < argv.length; i++) {
|
|
188
202
|
if (argv[i] === '--') { args._.push(...argv.slice(i + 1)); break; }
|
|
@@ -402,34 +416,42 @@ async function cmdBackfill(aquifer, args) {
|
|
|
402
416
|
if (failed > 0) process.exitCode = 2;
|
|
403
417
|
}
|
|
404
418
|
|
|
419
|
+
async function cmdBacklog(aquifer, args) {
|
|
420
|
+
const action = args.flags.plan || args.flags.action || 'inspect';
|
|
421
|
+
const opts = {
|
|
422
|
+
limit: parsePositiveInt(args.flags.limit, 50),
|
|
423
|
+
source: args.flags.source || undefined,
|
|
424
|
+
agentId: args.flags['agent-id'] || undefined,
|
|
425
|
+
status: args.flags.status || undefined,
|
|
426
|
+
action,
|
|
427
|
+
};
|
|
428
|
+
const report = await aquifer.getPendingWork(opts);
|
|
429
|
+
|
|
430
|
+
if (args.flags.json) {
|
|
431
|
+
console.log(JSON.stringify(buildBacklogEnvelope(report, {
|
|
432
|
+
diagnostics: args.flags.diagnostics === true,
|
|
433
|
+
includePlan: true,
|
|
434
|
+
}), null, 2));
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
printTextBlock(formatPendingWorkInterface(report, {
|
|
439
|
+
diagnostics: args.flags.diagnostics === true,
|
|
440
|
+
includePlan: true,
|
|
441
|
+
}));
|
|
442
|
+
}
|
|
443
|
+
|
|
405
444
|
async function cmdStats(aquifer, args) {
|
|
406
445
|
const stats = await aquifer.getStats();
|
|
407
446
|
|
|
408
447
|
if (args.flags.json) {
|
|
409
|
-
console.log(JSON.stringify(stats,
|
|
448
|
+
console.log(JSON.stringify(buildStatsEnvelope(stats, {
|
|
449
|
+
diagnostics: args.flags.diagnostics === true,
|
|
450
|
+
}), null, 2));
|
|
410
451
|
} else {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
console.log(`Sessions: ${stats.sessionTotal} (${Object.entries(stats.sessions).map(([k, v]) => `${k}: ${v}`).join(', ')})`);
|
|
415
|
-
console.log(`Summaries: ${stats.summaries}`);
|
|
416
|
-
console.log(`Turn embeddings: ${stats.turnEmbeddings}`);
|
|
417
|
-
console.log(`Entities: ${stats.entities}`);
|
|
418
|
-
if (stats.memoryRecords) {
|
|
419
|
-
console.log(`Memory records: ${stats.memoryRecords.total} (${stats.memoryRecords.active} active, ${stats.memoryRecords.visibleInRecall} recall-visible, ${stats.memoryRecords.visibleInBootstrap} bootstrap-visible)`);
|
|
420
|
-
if (stats.memoryRecords.latest) console.log(`Memory record range: ${formatDate(stats.memoryRecords.earliest, '?')} — ${formatDate(stats.memoryRecords.latest, '?')}`);
|
|
421
|
-
}
|
|
422
|
-
if (stats.sessionFinalizations?.available) {
|
|
423
|
-
const statusText = Object.entries(stats.sessionFinalizations.statuses || {})
|
|
424
|
-
.map(([status, count]) => `${status}: ${count}`)
|
|
425
|
-
.join(', ') || 'none';
|
|
426
|
-
console.log(`Session finalizations: ${stats.sessionFinalizations.total} (${statusText})`);
|
|
427
|
-
if (stats.sessionFinalizations.latestFinalizedAt) console.log(`Latest finalization: ${formatDate(stats.sessionFinalizations.latestFinalizedAt, '?')}`);
|
|
428
|
-
}
|
|
429
|
-
if (stats.earliest) console.log(`Range: ${formatDate(stats.earliest, '?')} — ${formatDate(stats.latest, '?')}`);
|
|
430
|
-
if ((stats.serving?.mode || 'legacy') !== 'curated') {
|
|
431
|
-
console.log('Warning: legacy serving returns session/evidence material; configure curated serving with an active scope for current-memory answers.');
|
|
432
|
-
}
|
|
452
|
+
printTextBlock(formatMemoryStatsInterface(stats, {
|
|
453
|
+
diagnostics: args.flags.diagnostics === true,
|
|
454
|
+
}));
|
|
433
455
|
}
|
|
434
456
|
}
|
|
435
457
|
|
|
@@ -473,6 +495,149 @@ async function cmdBackendInfo(args) {
|
|
|
473
495
|
}
|
|
474
496
|
}
|
|
475
497
|
|
|
498
|
+
function formatDoctor(result = {}) {
|
|
499
|
+
const checks = Array.isArray(result.checks) ? result.checks : [];
|
|
500
|
+
if (checks.length === 0) return `Doctor: ${result.status || 'unknown'}`;
|
|
501
|
+
return checks.map(check => {
|
|
502
|
+
const next = check.nextAction ? ` next=${check.nextAction}` : '';
|
|
503
|
+
return `${check.status || 'unknown'} ${check.id || 'check'}: ${check.summary || ''}${next}`;
|
|
504
|
+
}).join('\n');
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
async function cmdDoctor(aquifer, args) {
|
|
508
|
+
const result = await aquifer.doctor.run({
|
|
509
|
+
host: args.flags.host || undefined,
|
|
510
|
+
openclawHome: args.flags['openclaw-home'] || undefined,
|
|
511
|
+
limit: parsePositiveInt(args.flags.limit, 20),
|
|
512
|
+
});
|
|
513
|
+
if (args.flags.json) {
|
|
514
|
+
console.log(JSON.stringify(result, null, 2));
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
console.log(formatDoctor(result));
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function formatTimestamp(value) {
|
|
521
|
+
if (!value) return '?';
|
|
522
|
+
const parsed = new Date(value);
|
|
523
|
+
return isNaN(parsed.getTime()) ? String(value) : parsed.toISOString();
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function shortHash(value) {
|
|
527
|
+
if (!value) return '?';
|
|
528
|
+
return String(value).slice(0, 12);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
function formatFinalizationList(rows = []) {
|
|
532
|
+
if (!rows || rows.length === 0) return 'No finalization rows found.';
|
|
533
|
+
return rows.map(row => {
|
|
534
|
+
const item = summarizeFinalizationListRow(row);
|
|
535
|
+
const session = `${item.source}/${item.agentId}/${item.sessionId}`;
|
|
536
|
+
const phase = item.phase ? ` phase=${item.phase}` : '';
|
|
537
|
+
const mode = item.mode ? ` mode=${item.mode}` : '';
|
|
538
|
+
const hash = item.transcriptHashPrefix ? ` hash=${item.transcriptHashPrefix}` : '';
|
|
539
|
+
return `#${item.id} ${item.status} ${session}${phase}${mode}${hash} updated=${formatTimestamp(item.updatedAt)}`;
|
|
540
|
+
}).join('\n');
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
function formatFinalizationInspect(report = {}) {
|
|
544
|
+
const item = report.finalization || {};
|
|
545
|
+
const candidateSummary = report.candidateSummary || {};
|
|
546
|
+
const lineage = report.lineage || {};
|
|
547
|
+
const envelope = report.candidateEnvelope || {};
|
|
548
|
+
const memoryResult = report.memoryResult || {};
|
|
549
|
+
const lines = [
|
|
550
|
+
`Finalization #${item.id || '?'} ${item.status || 'unknown'}`,
|
|
551
|
+
`Session: ${item.source || '?'}/${item.agentId || '?'}/${item.sessionId || '?'} phase=${item.phase || '?'} mode=${item.mode || '?'} host=${item.host || '?'}`,
|
|
552
|
+
`Transcript hash: ${item.transcriptHashPrefix || shortHash(item.transcriptHash)}`,
|
|
553
|
+
`Updated: ${formatTimestamp(item.updatedAt)} finalized=${formatTimestamp(item.finalizedAt)}`,
|
|
554
|
+
];
|
|
555
|
+
|
|
556
|
+
if (item.finalizerModel) lines.push(`Finalizer: ${item.finalizerModel}`);
|
|
557
|
+
if (item.scopeKind || item.scopeKey || item.contextKey || item.topicKey) {
|
|
558
|
+
lines.push(`Scope: kind=${item.scopeKind || '?'} key=${item.scopeKey || '?'} context=${item.contextKey || '?'} topic=${item.topicKey || '?'}`);
|
|
559
|
+
}
|
|
560
|
+
if (item.error) lines.push(`Error: ${item.error}`);
|
|
561
|
+
|
|
562
|
+
lines.push(`Memory result: candidates=${memoryResult.candidates || 0} promoted=${memoryResult.promoted || 0} quarantined=${memoryResult.quarantined || 0} skipped=${memoryResult.skipped || 0}`);
|
|
563
|
+
lines.push(`Candidate envelope: version=${envelope.version || '?'} hash=${shortHash(envelope.hash)} candidates=${envelope.candidateCount || 0}`);
|
|
564
|
+
lines.push(`Candidate actions: total=${candidateSummary.total || 0} promote=${candidateSummary.promote || 0} quarantine=${candidateSummary.quarantine || 0} skip=${candidateSummary.skip || 0} supersede=${candidateSummary.supersede || 0} error=${candidateSummary.error || 0}`);
|
|
565
|
+
lines.push(`Lineage: memories=${(lineage.memoryRecordIds || []).join(',') || 'none'} facts=${(lineage.factAssertionIds || []).join(',') || 'none'} evidenceRefs=${lineage.evidenceRefCount || 0} evidenceItems=${lineage.evidenceItemCount || 0}`);
|
|
566
|
+
|
|
567
|
+
if (report.review?.humanReviewText) {
|
|
568
|
+
lines.push('\nHuman review:\n' + report.review.humanReviewText);
|
|
569
|
+
}
|
|
570
|
+
if (report.review?.sessionStartText) {
|
|
571
|
+
lines.push('\nSessionStart:\n' + report.review.sessionStartText);
|
|
572
|
+
}
|
|
573
|
+
if (Array.isArray(report.candidates) && report.candidates.length > 0) {
|
|
574
|
+
lines.push('\nCandidates:');
|
|
575
|
+
for (const candidate of report.candidates) {
|
|
576
|
+
lines.push(` [${candidate.index}] ${candidate.action}${candidate.reason ? `/${candidate.reason}` : ''} ${candidate.memoryType || '?'} ${candidate.canonicalKey || '?'}${candidate.memoryRecordId ? ` memory=${candidate.memoryRecordId}` : ''}`);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
return lines.join('\n');
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
async function cmdFinalization(aquifer, args) {
|
|
583
|
+
const verb = args._[1] || 'list';
|
|
584
|
+
|
|
585
|
+
if (verb === 'list') {
|
|
586
|
+
const rows = await aquifer.finalization.list({
|
|
587
|
+
status: args.flags.status || undefined,
|
|
588
|
+
agentId: args.flags['agent-id'] || undefined,
|
|
589
|
+
source: args.flags.source || undefined,
|
|
590
|
+
host: args.flags.host || undefined,
|
|
591
|
+
sessionId: args.flags['session-id'] || undefined,
|
|
592
|
+
transcriptHash: args.flags['transcript-hash'] || undefined,
|
|
593
|
+
phase: args.flags.phase || undefined,
|
|
594
|
+
mode: args.flags.mode || undefined,
|
|
595
|
+
limit: parsePositiveInt(args.flags.limit, 50),
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
if (args.flags.json) {
|
|
599
|
+
console.log(JSON.stringify({
|
|
600
|
+
readOnly: true,
|
|
601
|
+
finalizations: rows.map(summarizeFinalizationListRow),
|
|
602
|
+
}, null, 2));
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
console.log(formatFinalizationList(rows));
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
if (verb === 'inspect') {
|
|
610
|
+
const id = args.flags.id || args._[2] || undefined;
|
|
611
|
+
const sessionId = args.flags['session-id'];
|
|
612
|
+
if (id && (sessionId || args.flags['agent-id'] || args.flags.source || args.flags['transcript-hash'])) {
|
|
613
|
+
console.error('Usage: --id is mutually exclusive with --session-id/--agent-id/--source/--transcript-hash.');
|
|
614
|
+
process.exit(1);
|
|
615
|
+
}
|
|
616
|
+
if (!id && (!sessionId || !args.flags['agent-id'] || !args.flags.source)) {
|
|
617
|
+
console.error('Usage: aquifer finalization inspect (--id ID | --session-id ID --agent-id ID --source SOURCE [--transcript-hash HASH]) [--json]');
|
|
618
|
+
process.exit(1);
|
|
619
|
+
}
|
|
620
|
+
const report = await aquifer.finalization.inspect({
|
|
621
|
+
id,
|
|
622
|
+
sessionId: sessionId || undefined,
|
|
623
|
+
agentId: args.flags['agent-id'] || undefined,
|
|
624
|
+
source: args.flags.source || undefined,
|
|
625
|
+
transcriptHash: args.flags['transcript-hash'] || undefined,
|
|
626
|
+
phase: args.flags.phase || undefined,
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
if (args.flags.json) {
|
|
630
|
+
console.log(JSON.stringify(report, null, 2));
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
console.log(formatFinalizationInspect(report));
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
console.error('Usage: aquifer finalization <list|inspect> [options]');
|
|
638
|
+
process.exit(1);
|
|
639
|
+
}
|
|
640
|
+
|
|
476
641
|
async function cmdLocalQuickstart(aquifer) {
|
|
477
642
|
const cfg = aquifer.getConfig();
|
|
478
643
|
console.log('Aquifer quickstart — verifying local starter backend.\n');
|
|
@@ -644,10 +809,319 @@ async function cmdBootstrap(aquifer, args) {
|
|
|
644
809
|
}
|
|
645
810
|
}
|
|
646
811
|
|
|
812
|
+
function formatExplain(result = {}) {
|
|
813
|
+
const selected = Array.isArray(result.selected) ? result.selected : [];
|
|
814
|
+
const excluded = Array.isArray(result.excluded) ? result.excluded : [];
|
|
815
|
+
const lines = [
|
|
816
|
+
`Explain ${result.lane || 'memory'}: selected=${selected.length} excluded=${excluded.length}`,
|
|
817
|
+
];
|
|
818
|
+
if (selected.length > 0) {
|
|
819
|
+
lines.push('Selected:');
|
|
820
|
+
for (const row of selected) {
|
|
821
|
+
lines.push(` ${row.memoryId || row.id || '?'} ${row.canonicalKey || '?'} reason=${row.reason || 'selected'}`);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
if (excluded.length > 0) {
|
|
825
|
+
lines.push('Excluded:');
|
|
826
|
+
for (const row of excluded) {
|
|
827
|
+
lines.push(` ${row.memoryId || row.id || '?'} ${row.canonicalKey || '?'} reason=${row.reason || 'unknown'}`);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
if (result.budget) {
|
|
831
|
+
lines.push(`Budget: limit=${result.budget.limit || '?'} maxChars=${result.budget.maxChars || '?'} overflow=${result.budget.overflow === true}`);
|
|
832
|
+
}
|
|
833
|
+
return lines.join('\n');
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
function formatFeedbackCounts(counts = {}) {
|
|
837
|
+
const entries = Object.entries(counts).filter(([, count]) => count > 0);
|
|
838
|
+
if (entries.length === 0) return 'none';
|
|
839
|
+
return entries.map(([type, count]) => `${type}=${count}`).join(' ');
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
function formatReviewResolution(resolution = null) {
|
|
843
|
+
if (!resolution || !resolution.resolution) return 'none';
|
|
844
|
+
const at = resolution.resolvedAt ? ` at=${formatTimestamp(resolution.resolvedAt)}` : '';
|
|
845
|
+
const defer = resolution.deferUntil ? ` deferUntil=${formatTimestamp(resolution.deferUntil)}` : '';
|
|
846
|
+
return `${resolution.resolution}${at}${defer}`;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
function formatReviewQueue(result = {}) {
|
|
850
|
+
if (result.available === false) {
|
|
851
|
+
return result.error || 'Memory review queue is unavailable.';
|
|
852
|
+
}
|
|
853
|
+
const rows = Array.isArray(result.items) ? result.items : (Array.isArray(result.reviewQueue) ? result.reviewQueue : []);
|
|
854
|
+
if (rows.length === 0) return 'No memory review items found.';
|
|
855
|
+
return rows.map(row => {
|
|
856
|
+
const scope = row.scope?.key ? ` scope=${row.scope.key}` : '';
|
|
857
|
+
const latest = row.latestFeedbackAt ? ` latest=${formatTimestamp(row.latestFeedbackAt)}` : '';
|
|
858
|
+
const resolution = row.resolution ? ` resolution=${formatReviewResolution(row.resolution)}` : '';
|
|
859
|
+
const counts = formatFeedbackCounts(row.feedbackCounts);
|
|
860
|
+
return `#${row.memoryId} severity=${row.severityScore} issues=${row.issueCount}/${row.feedbackCount} ${row.status || '?'}${scope} ${row.canonicalKey || '?'} feedback=${counts}${latest}${resolution}`;
|
|
861
|
+
}).join('\n');
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
function formatReviewInspect(result = {}) {
|
|
865
|
+
const memory = result.memory || {};
|
|
866
|
+
const review = result.review || {};
|
|
867
|
+
const visibility = memory.visibility || {};
|
|
868
|
+
const lines = [
|
|
869
|
+
`Memory #${memory.memoryId || '?'} ${memory.status || '?'} ${memory.canonicalKey || '?'}`,
|
|
870
|
+
`Scope: ${memory.scope?.kind || '?'}/${memory.scope?.key || '?'}`,
|
|
871
|
+
`Visibility: bootstrap=${visibility.bootstrap === true} recall=${visibility.recall === true}`,
|
|
872
|
+
`Feedback: issues=${review.issueCount || 0}/${review.feedbackCount || 0} ${formatFeedbackCounts(review.feedbackCounts)}`,
|
|
873
|
+
`Latest resolution: ${formatReviewResolution(review.latestResolution)}`,
|
|
874
|
+
];
|
|
875
|
+
const events = Array.isArray(review.recentFeedback) ? review.recentFeedback : [];
|
|
876
|
+
if (events.length > 0) {
|
|
877
|
+
lines.push('Recent feedback:');
|
|
878
|
+
for (const event of events) {
|
|
879
|
+
const actor = event.actorId ? `${event.actorKind || 'actor'}:${event.actorId}` : (event.actorKind || 'actor');
|
|
880
|
+
lines.push(` #${event.id} ${event.feedbackType} ${actor} at=${formatTimestamp(event.createdAt)}`);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
return lines.join('\n');
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
function formatReviewResolve(result = {}) {
|
|
887
|
+
const resolution = result.resolution || {};
|
|
888
|
+
const memory = result.memory || {};
|
|
889
|
+
const issueCount = result.review?.issueFeedbackCount || 0;
|
|
890
|
+
return [
|
|
891
|
+
`Review resolution recorded: ${resolution.resolution || '?'} for memory #${memory.memoryId || resolution.memoryId || '?'}`,
|
|
892
|
+
`Canonical key: ${memory.canonicalKey || resolution.canonicalKey || '?'}`,
|
|
893
|
+
`Issue feedback covered: ${issueCount} ${formatFeedbackCounts(result.review?.issueFeedbackCounts)}`,
|
|
894
|
+
`Memory mutated: ${result.memoryMutated === true}`,
|
|
895
|
+
].join('\n');
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
async function cmdReview(aquifer, args) {
|
|
899
|
+
const verb = args._[1] || 'queue';
|
|
900
|
+
if (verb === 'queue') {
|
|
901
|
+
const activeScopePath = parseScopePath(args.flags['active-scope-path']);
|
|
902
|
+
const activeScopeKey = args.flags['active-scope-key']
|
|
903
|
+
|| args.flags['scope-key']
|
|
904
|
+
|| (activeScopePath ? activeScopePath[activeScopePath.length - 1] : undefined);
|
|
905
|
+
const result = await aquifer.review.queue({
|
|
906
|
+
feedbackType: args.flags['feedback-type'] || undefined,
|
|
907
|
+
memoryType: args.flags['memory-type'] || undefined,
|
|
908
|
+
visibility: args.flags.visibility || undefined,
|
|
909
|
+
activeScopeKey,
|
|
910
|
+
activeScopePath,
|
|
911
|
+
scopeKey: args.flags['scope-key'] || activeScopeKey,
|
|
912
|
+
canonicalKey: args.flags['canonical-key'] || undefined,
|
|
913
|
+
dateFrom: args.flags['date-from'] || undefined,
|
|
914
|
+
dateTo: args.flags['date-to'] || undefined,
|
|
915
|
+
asOf: args.flags['as-of'] || args.flags['snapshot-as-of'] || undefined,
|
|
916
|
+
includeResolved: args.flags['include-resolved'] === true,
|
|
917
|
+
limit: parsePositiveInt(args.flags.limit, 20),
|
|
918
|
+
});
|
|
919
|
+
if (args.flags.json) {
|
|
920
|
+
console.log(JSON.stringify(result, null, 2));
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
console.log(formatReviewQueue(result));
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
if (verb === 'inspect') {
|
|
928
|
+
const activeScopePath = parseScopePath(args.flags['active-scope-path']);
|
|
929
|
+
const activeScopeKey = args.flags['active-scope-key']
|
|
930
|
+
|| args.flags['scope-key']
|
|
931
|
+
|| (activeScopePath ? activeScopePath[activeScopePath.length - 1] : undefined);
|
|
932
|
+
const memoryId = args.flags['memory-id'] || args.flags.id || args._[2] || undefined;
|
|
933
|
+
const canonicalKey = args.flags['canonical-key'] || undefined;
|
|
934
|
+
if (memoryId && canonicalKey) {
|
|
935
|
+
console.error('Usage: --memory-id/--id is mutually exclusive with --canonical-key.');
|
|
936
|
+
process.exit(1);
|
|
937
|
+
}
|
|
938
|
+
if (!memoryId && !canonicalKey) {
|
|
939
|
+
console.error('Usage: aquifer review inspect (--memory-id ID | --canonical-key KEY) [--json]');
|
|
940
|
+
process.exit(1);
|
|
941
|
+
}
|
|
942
|
+
const result = await aquifer.review.inspect({
|
|
943
|
+
memoryId,
|
|
944
|
+
canonicalKey,
|
|
945
|
+
activeScopeKey,
|
|
946
|
+
activeScopePath,
|
|
947
|
+
scopeKey: args.flags['scope-key'] || activeScopeKey,
|
|
948
|
+
visibility: args.flags.visibility || undefined,
|
|
949
|
+
feedbackType: args.flags['feedback-type'] || undefined,
|
|
950
|
+
dateFrom: args.flags['date-from'] || undefined,
|
|
951
|
+
dateTo: args.flags['date-to'] || undefined,
|
|
952
|
+
asOf: args.flags['as-of'] || args.flags['snapshot-as-of'] || undefined,
|
|
953
|
+
limit: parsePositiveInt(args.flags.limit, 20),
|
|
954
|
+
});
|
|
955
|
+
if (args.flags.json) {
|
|
956
|
+
console.log(JSON.stringify(result, null, 2));
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
console.log(formatReviewInspect(result));
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
if (verb === 'resolve') {
|
|
964
|
+
const activeScopePath = parseScopePath(args.flags['active-scope-path']);
|
|
965
|
+
const activeScopeKey = args.flags['active-scope-key']
|
|
966
|
+
|| args.flags['scope-key']
|
|
967
|
+
|| (activeScopePath ? activeScopePath[activeScopePath.length - 1] : undefined);
|
|
968
|
+
const memoryId = args.flags['memory-id'] || args.flags.id || undefined;
|
|
969
|
+
const canonicalKey = args.flags['canonical-key'] || undefined;
|
|
970
|
+
if (memoryId && canonicalKey) {
|
|
971
|
+
console.error('Usage: --memory-id/--id is mutually exclusive with --canonical-key.');
|
|
972
|
+
process.exit(1);
|
|
973
|
+
}
|
|
974
|
+
if (!memoryId && !canonicalKey) {
|
|
975
|
+
console.error('Usage: aquifer review resolve (--memory-id ID | --canonical-key KEY) --resolution resolved|ignored|deferred [--json]');
|
|
976
|
+
process.exit(1);
|
|
977
|
+
}
|
|
978
|
+
if (!args.flags['expected-latest-issue-feedback-id'] && !args.flags['expected-latest-issue-feedback-at']) {
|
|
979
|
+
console.error('Usage: aquifer review resolve requires --expected-latest-issue-feedback-id or --expected-latest-issue-feedback-at.');
|
|
980
|
+
process.exit(1);
|
|
981
|
+
}
|
|
982
|
+
const result = await aquifer.review.resolve({
|
|
983
|
+
memoryId,
|
|
984
|
+
canonicalKey,
|
|
985
|
+
resolution: args.flags.resolution || undefined,
|
|
986
|
+
reason: args.flags.reason || args.flags.note || undefined,
|
|
987
|
+
actorKind: args.flags['actor-kind'] || undefined,
|
|
988
|
+
actorId: args.flags['actor-id'] || args.flags['agent-id'] || undefined,
|
|
989
|
+
deferUntil: args.flags['defer-until'] || undefined,
|
|
990
|
+
expectedLatestIssueFeedbackId: args.flags['expected-latest-issue-feedback-id'] || undefined,
|
|
991
|
+
expectedLatestIssueFeedbackAt: args.flags['expected-latest-issue-feedback-at'] || undefined,
|
|
992
|
+
activeScopeKey,
|
|
993
|
+
activeScopePath,
|
|
994
|
+
scopeKey: args.flags['scope-key'] || activeScopeKey,
|
|
995
|
+
visibility: args.flags.visibility || undefined,
|
|
996
|
+
asOf: args.flags['as-of'] || args.flags['snapshot-as-of'] || undefined,
|
|
997
|
+
});
|
|
998
|
+
if (args.flags.json) {
|
|
999
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
console.log(formatReviewResolve(result));
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
console.error('Usage: aquifer review <queue|inspect|resolve> [options]');
|
|
1007
|
+
process.exit(1);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
async function cmdExplain(aquifer, args) {
|
|
1011
|
+
const lane = args._[1] || 'bootstrap';
|
|
1012
|
+
if (lane === 'bootstrap') {
|
|
1013
|
+
const result = await aquifer.memory.explainBootstrap({
|
|
1014
|
+
activeScopeKey: args.flags['active-scope-key'] || undefined,
|
|
1015
|
+
activeScopePath: parseScopePath(args.flags['active-scope-path']),
|
|
1016
|
+
limit: parsePositiveInt(args.flags.limit, 5),
|
|
1017
|
+
maxChars: parsePositiveInt(args.flags['max-chars'], 4000),
|
|
1018
|
+
});
|
|
1019
|
+
if (args.flags.json) {
|
|
1020
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
console.log(formatExplain(result));
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
if (lane === 'memory') {
|
|
1027
|
+
const query = args.flags.query || args._.slice(2).join(' ');
|
|
1028
|
+
if (!query) {
|
|
1029
|
+
console.error('Usage: aquifer explain memory --query TEXT --active-scope-key KEY [--limit N] [--json]');
|
|
1030
|
+
process.exit(1);
|
|
1031
|
+
}
|
|
1032
|
+
const result = await aquifer.memory.explainCurrent(query, {
|
|
1033
|
+
activeScopeKey: args.flags['active-scope-key'] || undefined,
|
|
1034
|
+
activeScopePath: parseScopePath(args.flags['active-scope-path']),
|
|
1035
|
+
limit: parsePositiveInt(args.flags.limit, 5),
|
|
1036
|
+
});
|
|
1037
|
+
if (args.flags.json) {
|
|
1038
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
console.log(formatExplain(result));
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
console.error('Usage: aquifer explain <bootstrap|memory> [options]');
|
|
1045
|
+
process.exit(1);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
function formatOperatorStatus(result = {}) {
|
|
1049
|
+
const compaction = result.compaction || {};
|
|
1050
|
+
const checkpoint = result.checkpoint || {};
|
|
1051
|
+
const lines = [
|
|
1052
|
+
`Compaction: ${compaction.available === false ? 'unavailable' : 'available'} statuses=${JSON.stringify(compaction.statusCounts || {})}`,
|
|
1053
|
+
`Checkpoint: ${checkpoint.available === false ? 'unavailable' : 'available'} statuses=${JSON.stringify(checkpoint.statusCounts || {})}`,
|
|
1054
|
+
];
|
|
1055
|
+
if (Array.isArray(compaction.staleClaims) && compaction.staleClaims.length > 0) {
|
|
1056
|
+
lines.push(`Stale compaction claims: ${compaction.staleClaims.map(run => `#${run.id}/${run.cadence}`).join(', ')}`);
|
|
1057
|
+
}
|
|
1058
|
+
if (Array.isArray(compaction.latest) && compaction.latest.length > 0) {
|
|
1059
|
+
lines.push('Latest compaction: ' + compaction.latest.map(run => `#${run.id} ${run.status} ${run.cadence}`).join(', '));
|
|
1060
|
+
}
|
|
1061
|
+
if (Array.isArray(checkpoint.latest) && checkpoint.latest.length > 0) {
|
|
1062
|
+
lines.push('Latest checkpoint: ' + checkpoint.latest.map(run => `#${run.id} ${run.status} sources=${run.sourceCount}`).join(', '));
|
|
1063
|
+
}
|
|
1064
|
+
return lines.join('\n');
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
function formatOperatorInspect(result = {}) {
|
|
1068
|
+
const run = result.run || {};
|
|
1069
|
+
const lines = [
|
|
1070
|
+
`${run.kind || 'operator'} run #${run.id || '?'} status=${run.status || '?'}`,
|
|
1071
|
+
];
|
|
1072
|
+
if (run.kind === 'compaction') {
|
|
1073
|
+
lines.push(`Window: ${run.cadence || '?'} ${run.periodStart || '?'} -> ${run.periodEnd || '?'}`);
|
|
1074
|
+
lines.push(`Plan: candidates=${run.candidateCount || 0} statusUpdates=${run.statusUpdateCount || 0}`);
|
|
1075
|
+
if (run.leaseExpiresAt) lines.push(`Claim: worker=${run.workerId || '?'} leaseExpiresAt=${run.leaseExpiresAt}`);
|
|
1076
|
+
} else if (run.kind === 'checkpoint') {
|
|
1077
|
+
lines.push(`Checkpoint: scope=${run.scopeId || '?'} key=${run.checkpointKey || '?'}`);
|
|
1078
|
+
lines.push(`Range: ${run.fromFinalizationIdExclusive || 0} -> ${run.toFinalizationIdInclusive || '?'}`);
|
|
1079
|
+
lines.push(`Sources: ${run.sourceCount || 0}`);
|
|
1080
|
+
}
|
|
1081
|
+
if (run.error) lines.push(`Error: ${run.error}`);
|
|
1082
|
+
if (Array.isArray(result.sources) && result.sources.length > 0) {
|
|
1083
|
+
lines.push('Sources:');
|
|
1084
|
+
for (const source of result.sources) {
|
|
1085
|
+
lines.push(` [${source.sourceIndex}] finalization=${source.finalizationId} ${source.source || '?'}/${source.agentId || '?'}/${source.sessionId || '?'}`);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
return lines.join('\n');
|
|
1089
|
+
}
|
|
1090
|
+
|
|
647
1091
|
async function cmdOperator(aquifer, args) {
|
|
648
1092
|
const operatorVerb = args._[1] || 'compaction';
|
|
649
1093
|
const cadenceVerbs = new Set(['manual', 'daily', 'weekly', 'monthly']);
|
|
650
1094
|
|
|
1095
|
+
if (operatorVerb === 'status') {
|
|
1096
|
+
const result = await aquifer.operator.status({
|
|
1097
|
+
limit: parsePositiveInt(args.flags.limit, 10),
|
|
1098
|
+
});
|
|
1099
|
+
if (args.flags.json) {
|
|
1100
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
console.log(formatOperatorStatus(result));
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
if (operatorVerb === 'inspect') {
|
|
1108
|
+
const runId = args.flags['run-id'] || args.flags.id || args._[2];
|
|
1109
|
+
if (!runId) {
|
|
1110
|
+
console.error('Usage: aquifer operator inspect --run-id ID [--kind compaction|checkpoint] [--json]');
|
|
1111
|
+
process.exit(1);
|
|
1112
|
+
}
|
|
1113
|
+
const result = await aquifer.operator.inspect({
|
|
1114
|
+
runId,
|
|
1115
|
+
kind: args.flags.kind || 'compaction',
|
|
1116
|
+
});
|
|
1117
|
+
if (args.flags.json) {
|
|
1118
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
console.log(formatOperatorInspect(result));
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
651
1125
|
if (operatorVerb === 'checkpoint') {
|
|
652
1126
|
const synthesisSummary = readSynthesisSummaryFromFlags(args.flags);
|
|
653
1127
|
const result = await aquifer.checkpoints.runProducer({
|
|
@@ -830,15 +1304,21 @@ Commands:
|
|
|
830
1304
|
quickstart Verify end-to-end setup (migrate → commit → enrich → recall)
|
|
831
1305
|
migrate Run database migrations
|
|
832
1306
|
backend-info Show selected backend capabilities without connecting to a database
|
|
1307
|
+
install-openclaw Install/update OpenClaw MCP + extension wiring
|
|
1308
|
+
doctor Run read-only health diagnostics
|
|
833
1309
|
recall <query> Search sessions (requires embed config)
|
|
834
1310
|
evidence-recall <query> Search legacy session/evidence plane explicitly
|
|
835
1311
|
feedback Record trust feedback on a session
|
|
836
1312
|
memory-feedback Record curated memory feedback
|
|
837
1313
|
feedback-stats Show trust feedback statistics and coverage
|
|
1314
|
+
review ... Inspect or resolve memory feedback review queue
|
|
838
1315
|
backfill Enrich pending sessions
|
|
1316
|
+
backlog Explain and plan saved-content preparation work
|
|
839
1317
|
operator ... Run operator-safe consolidation jobs
|
|
1318
|
+
finalization ... Inspect read-only finalization ledger
|
|
1319
|
+
explain ... Explain current-memory serving decisions
|
|
840
1320
|
compact Plan or apply curated memory compaction
|
|
841
|
-
stats
|
|
1321
|
+
stats Check memory readiness
|
|
842
1322
|
export Export sessions as JSONL
|
|
843
1323
|
bootstrap Show recent session context (for new session start)
|
|
844
1324
|
codex-recovery ... Inspect or run Codex recovery/checkpoint flows
|
|
@@ -853,11 +1333,35 @@ Options:
|
|
|
853
1333
|
--date-to YYYY-MM-DD End date
|
|
854
1334
|
--entities A,B,C Entity names (comma-separated, recall)
|
|
855
1335
|
--entity-mode any|all Entity match mode (recall, default: any)
|
|
1336
|
+
--id ID Finalization row id
|
|
1337
|
+
--host HOST Finalization host filter
|
|
1338
|
+
--status STATUS Finalization status filter
|
|
1339
|
+
--plan inspect|backfill|skip
|
|
1340
|
+
Saved-content dry-run action plan
|
|
1341
|
+
--diagnostics Include raw counters, buckets, samples, and serving diagnostics
|
|
1342
|
+
--phase PHASE Finalization phase filter
|
|
1343
|
+
--transcript-hash HASH Finalization transcript hash filter
|
|
1344
|
+
--run-id ID Operator run id
|
|
1345
|
+
--kind KIND Operator inspect kind: compaction|checkpoint
|
|
1346
|
+
--query TEXT Explain memory query
|
|
856
1347
|
--session-id ID Session ID (feedback)
|
|
857
|
-
--memory-id ID Curated memory record ID (memory-feedback)
|
|
858
|
-
--canonical-key KEY Active curated memory canonical key (memory-feedback)
|
|
1348
|
+
--memory-id ID Curated memory record ID (memory-feedback, review inspect/resolve)
|
|
1349
|
+
--canonical-key KEY Active curated memory canonical key (memory-feedback, review queue/inspect/resolve)
|
|
859
1350
|
--verdict helpful|unhelpful Feedback verdict (feedback)
|
|
860
1351
|
--feedback-type TYPE Curated memory feedback type
|
|
1352
|
+
--memory-type TYPE Curated memory type filter (review queue)
|
|
1353
|
+
--visibility MODE Review visibility filter: either|both|bootstrap|recall
|
|
1354
|
+
--as-of ISO Review queue memory validity instant
|
|
1355
|
+
--include-resolved Include currently resolved review items in review queue
|
|
1356
|
+
--resolution ACTION Review resolution: resolved|ignored|deferred
|
|
1357
|
+
--reason TEXT Operator reason for review resolution
|
|
1358
|
+
--actor-kind KIND Review resolution actor kind: user|agent|system|curator
|
|
1359
|
+
--actor-id ID Review resolution actor id
|
|
1360
|
+
--defer-until ISO Re-open deferred review item after this instant
|
|
1361
|
+
--expected-latest-issue-feedback-id ID
|
|
1362
|
+
Reject review resolution if newer issue feedback exists
|
|
1363
|
+
--expected-latest-issue-feedback-at ISO
|
|
1364
|
+
Timestamp guard for review resolution snapshots
|
|
861
1365
|
--note TEXT Feedback note (feedback)
|
|
862
1366
|
--explain Show score breakdown per result (recall)
|
|
863
1367
|
--allow-unsafe-debug Allow broad evidence-recall without audit boundary
|
|
@@ -865,6 +1369,11 @@ Options:
|
|
|
865
1369
|
--dry-run Preview only (backfill)
|
|
866
1370
|
--output PATH Output file (export)
|
|
867
1371
|
--config PATH Config file path
|
|
1372
|
+
--openclaw-home PATH OpenClaw home path (install-openclaw)
|
|
1373
|
+
--skip-extension Do not wire the OpenClaw extension/plugin (install-openclaw)
|
|
1374
|
+
--skip-mcp Do not update mcp.servers.aquifer (install-openclaw)
|
|
1375
|
+
--force Move aside existing extension path if needed (install-openclaw)
|
|
1376
|
+
--link-current-package Development only: wire the current checkout instead of OpenClaw node_modules
|
|
868
1377
|
--lookback-days N How far back in days (bootstrap, default: 14)
|
|
869
1378
|
--max-chars N Max output characters (bootstrap, default: 4000)
|
|
870
1379
|
--active-scope-key KEY Active curated memory scope key
|
|
@@ -890,6 +1399,17 @@ Options:
|
|
|
890
1399
|
--min-messages N Min user messages to ingest (ingest-opencode, default: 3)
|
|
891
1400
|
|
|
892
1401
|
Operator examples:
|
|
1402
|
+
aquifer doctor --json
|
|
1403
|
+
aquifer finalization list --status finalized --json
|
|
1404
|
+
aquifer finalization inspect --id 42 --json
|
|
1405
|
+
aquifer finalization inspect --session-id SESSION --agent-id main --source codex --transcript-hash HASH
|
|
1406
|
+
aquifer explain bootstrap --active-scope-key project:aquifer --json
|
|
1407
|
+
aquifer explain memory --query "serving contract" --active-scope-key project:aquifer --json
|
|
1408
|
+
aquifer review queue --scope-key project:aquifer --feedback-type incorrect --json
|
|
1409
|
+
aquifer review inspect --memory-id 42 --json
|
|
1410
|
+
aquifer review resolve --memory-id 42 --resolution resolved --reason "verified current" --json
|
|
1411
|
+
aquifer operator status --json
|
|
1412
|
+
aquifer operator inspect --run-id 42 --kind compaction --json
|
|
893
1413
|
aquifer operator compaction daily --json
|
|
894
1414
|
aquifer operator compaction daily --include-synthesis-prompt --json
|
|
895
1415
|
aquifer operator compaction manual --period-start 2026-04-27T00:00:00Z --period-end 2026-04-28T00:00:00Z --apply
|
|
@@ -898,7 +1418,9 @@ Operator examples:
|
|
|
898
1418
|
aquifer operator checkpoint --scope-id 7 --synthesis-summary-file /tmp/checkpoint-summary.json --apply --finalize --json
|
|
899
1419
|
AQUIFER_BACKEND=local aquifer backend-info --json
|
|
900
1420
|
aquifer codex-recovery checkpoint-heartbeat --hook-stdin --scope-key project:aquifer
|
|
1421
|
+
aquifer codex-recovery checkpoint-spool-status --json --limit 10
|
|
901
1422
|
aquifer codex-recovery checkpoint-heartbeat-hook --scope-key project:aquifer --hooks-path "$CODEX_HOME/hooks.json" --json
|
|
1423
|
+
aquifer install-openclaw --openclaw-home "$OPENCLAW_HOME"
|
|
902
1424
|
aquifer operator archive-distill --input /tmp/archive-snapshot.json --json`);
|
|
903
1425
|
process.exit(0);
|
|
904
1426
|
}
|
|
@@ -939,6 +1461,11 @@ Operator examples:
|
|
|
939
1461
|
return;
|
|
940
1462
|
}
|
|
941
1463
|
|
|
1464
|
+
if (command === 'install-openclaw') {
|
|
1465
|
+
await require('./openclaw-install').cmdInstallOpenClaw(args);
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
942
1469
|
// All other commands need an Aquifer instance
|
|
943
1470
|
const configOverrides = {};
|
|
944
1471
|
if (args.flags.config) {
|
|
@@ -986,6 +1513,9 @@ Operator examples:
|
|
|
986
1513
|
case 'migrate':
|
|
987
1514
|
await cmdMigrate(aquifer, args);
|
|
988
1515
|
break;
|
|
1516
|
+
case 'doctor':
|
|
1517
|
+
await cmdDoctor(aquifer, args);
|
|
1518
|
+
break;
|
|
989
1519
|
case 'recall':
|
|
990
1520
|
await cmdRecall(aquifer, args);
|
|
991
1521
|
break;
|
|
@@ -1001,12 +1531,24 @@ Operator examples:
|
|
|
1001
1531
|
case 'feedback-stats':
|
|
1002
1532
|
await cmdFeedbackStats(aquifer, args);
|
|
1003
1533
|
break;
|
|
1534
|
+
case 'review':
|
|
1535
|
+
await cmdReview(aquifer, args);
|
|
1536
|
+
break;
|
|
1004
1537
|
case 'backfill':
|
|
1005
1538
|
await cmdBackfill(aquifer, args);
|
|
1006
1539
|
break;
|
|
1540
|
+
case 'backlog':
|
|
1541
|
+
await cmdBacklog(aquifer, args);
|
|
1542
|
+
break;
|
|
1007
1543
|
case 'operator':
|
|
1008
1544
|
await cmdOperator(aquifer, args);
|
|
1009
1545
|
break;
|
|
1546
|
+
case 'finalization':
|
|
1547
|
+
await cmdFinalization(aquifer, args);
|
|
1548
|
+
break;
|
|
1549
|
+
case 'explain':
|
|
1550
|
+
await cmdExplain(aquifer, args);
|
|
1551
|
+
break;
|
|
1010
1552
|
case 'compact':
|
|
1011
1553
|
await cmdCompact(aquifer, args);
|
|
1012
1554
|
break;
|
|
@@ -1039,8 +1581,20 @@ module.exports = {
|
|
|
1039
1581
|
selectedBackendInfo,
|
|
1040
1582
|
cmdBackendInfo,
|
|
1041
1583
|
cmdMigrate,
|
|
1584
|
+
cmdDoctor,
|
|
1042
1585
|
cmdLocalQuickstart,
|
|
1043
1586
|
cmdOperator,
|
|
1587
|
+
cmdBacklog,
|
|
1588
|
+
cmdFinalization,
|
|
1589
|
+
cmdExplain,
|
|
1590
|
+
cmdReview,
|
|
1591
|
+
formatDoctor,
|
|
1592
|
+
formatFinalizationList,
|
|
1593
|
+
formatFinalizationInspect,
|
|
1594
|
+
formatExplain,
|
|
1595
|
+
formatReviewQueue,
|
|
1596
|
+
formatReviewInspect,
|
|
1597
|
+
cmdInstallOpenClaw: require('./openclaw-install').cmdInstallOpenClaw,
|
|
1044
1598
|
readSynthesisSummaryFromFlags,
|
|
1045
1599
|
};
|
|
1046
1600
|
|