@cleocode/cleo 2026.4.161 → 2026.5.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/dist/backfill/audit-columns.d.ts +105 -0
- package/dist/backfill/audit-columns.d.ts.map +1 -0
- package/dist/backfill/audit-columns.js +258 -0
- package/dist/backfill/audit-columns.js.map +1 -0
- package/dist/cli/commands/adapter.d.ts +28 -0
- package/dist/cli/commands/adapter.d.ts.map +1 -0
- package/dist/cli/commands/adapter.js +119 -0
- package/dist/cli/commands/adapter.js.map +1 -0
- package/dist/cli/commands/add-batch.d.ts +33 -0
- package/dist/cli/commands/add-batch.d.ts.map +1 -0
- package/dist/cli/commands/add-batch.js +148 -0
- package/dist/cli/commands/add-batch.js.map +1 -0
- package/dist/cli/commands/add.d.ts +162 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +279 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/admin.d.ts +24 -0
- package/dist/cli/commands/admin.d.ts.map +1 -0
- package/dist/cli/commands/admin.js +283 -0
- package/dist/cli/commands/admin.js.map +1 -0
- package/dist/cli/commands/adr.d.ts +33 -0
- package/dist/cli/commands/adr.d.ts.map +1 -0
- package/dist/cli/commands/adr.js +147 -0
- package/dist/cli/commands/adr.js.map +1 -0
- package/dist/cli/commands/agent-profile-status.d.ts +98 -0
- package/dist/cli/commands/agent-profile-status.d.ts.map +1 -0
- package/dist/cli/commands/agent-profile-status.js +71 -0
- package/dist/cli/commands/agent-profile-status.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +47 -0
- package/dist/cli/commands/agent.d.ts.map +1 -0
- package/dist/cli/commands/agent.js +2976 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +21 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +32 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/archive-stats.d.ts +66 -0
- package/dist/cli/commands/archive-stats.d.ts.map +1 -0
- package/dist/cli/commands/archive-stats.js +93 -0
- package/dist/cli/commands/archive-stats.js.map +1 -0
- package/dist/cli/commands/archive.d.ts +42 -0
- package/dist/cli/commands/archive.d.ts.map +1 -0
- package/dist/cli/commands/archive.js +59 -0
- package/dist/cli/commands/archive.js.map +1 -0
- package/dist/cli/commands/audit.d.ts +22 -0
- package/dist/cli/commands/audit.d.ts.map +1 -0
- package/dist/cli/commands/audit.js +137 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/backfill.d.ts +56 -0
- package/dist/cli/commands/backfill.d.ts.map +1 -0
- package/dist/cli/commands/backfill.js +161 -0
- package/dist/cli/commands/backfill.js.map +1 -0
- package/dist/cli/commands/backup-inspect.d.ts +33 -0
- package/dist/cli/commands/backup-inspect.d.ts.map +1 -0
- package/dist/cli/commands/backup-inspect.js +430 -0
- package/dist/cli/commands/backup-inspect.js.map +1 -0
- package/dist/cli/commands/backup.d.ts +23 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +564 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/blockers.d.ts +20 -0
- package/dist/cli/commands/blockers.d.ts.map +1 -0
- package/dist/cli/commands/blockers.js +31 -0
- package/dist/cli/commands/blockers.js.map +1 -0
- package/dist/cli/commands/brain.d.ts +37 -0
- package/dist/cli/commands/brain.d.ts.map +1 -0
- package/dist/cli/commands/brain.js +445 -0
- package/dist/cli/commands/brain.js.map +1 -0
- package/dist/cli/commands/briefing.d.ts +52 -0
- package/dist/cli/commands/briefing.d.ts.map +1 -0
- package/dist/cli/commands/briefing.js +69 -0
- package/dist/cli/commands/briefing.js.map +1 -0
- package/dist/cli/commands/bug.d.ts +61 -0
- package/dist/cli/commands/bug.d.ts.map +1 -0
- package/dist/cli/commands/bug.js +198 -0
- package/dist/cli/commands/bug.js.map +1 -0
- package/dist/cli/commands/cancel.d.ts +26 -0
- package/dist/cli/commands/cancel.d.ts.map +1 -0
- package/dist/cli/commands/cancel.js +40 -0
- package/dist/cli/commands/cancel.js.map +1 -0
- package/dist/cli/commands/cant.d.ts +13 -0
- package/dist/cli/commands/cant.d.ts.map +1 -0
- package/dist/cli/commands/cant.js +245 -0
- package/dist/cli/commands/cant.js.map +1 -0
- package/dist/cli/commands/chain.d.ts +24 -0
- package/dist/cli/commands/chain.d.ts.map +1 -0
- package/dist/cli/commands/chain.js +116 -0
- package/dist/cli/commands/chain.js.map +1 -0
- package/dist/cli/commands/check.d.ts +18 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +280 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/checkpoint.d.ts +27 -0
- package/dist/cli/commands/checkpoint.d.ts.map +1 -0
- package/dist/cli/commands/checkpoint.js +105 -0
- package/dist/cli/commands/checkpoint.js.map +1 -0
- package/dist/cli/commands/claim.d.ts +35 -0
- package/dist/cli/commands/claim.d.ts.map +1 -0
- package/dist/cli/commands/claim.js +35 -0
- package/dist/cli/commands/claim.js.map +1 -0
- package/dist/cli/commands/code.d.ts +22 -0
- package/dist/cli/commands/code.d.ts.map +1 -0
- package/dist/cli/commands/code.js +161 -0
- package/dist/cli/commands/code.js.map +1 -0
- package/dist/cli/commands/complete.d.ts +49 -0
- package/dist/cli/commands/complete.d.ts.map +1 -0
- package/dist/cli/commands/complete.js +83 -0
- package/dist/cli/commands/complete.js.map +1 -0
- package/dist/cli/commands/complexity.d.ts +13 -0
- package/dist/cli/commands/complexity.d.ts.map +1 -0
- package/dist/cli/commands/complexity.js +32 -0
- package/dist/cli/commands/complexity.js.map +1 -0
- package/dist/cli/commands/compliance.d.ts +27 -0
- package/dist/cli/commands/compliance.d.ts.map +1 -0
- package/dist/cli/commands/compliance.js +233 -0
- package/dist/cli/commands/compliance.js.map +1 -0
- package/dist/cli/commands/conduit.d.ts +28 -0
- package/dist/cli/commands/conduit.d.ts.map +1 -0
- package/dist/cli/commands/conduit.js +279 -0
- package/dist/cli/commands/conduit.js.map +1 -0
- package/dist/cli/commands/config.d.ts +25 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +132 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/consensus.d.ts +21 -0
- package/dist/cli/commands/consensus.d.ts.map +1 -0
- package/dist/cli/commands/consensus.js +100 -0
- package/dist/cli/commands/consensus.js.map +1 -0
- package/dist/cli/commands/context.d.ts +19 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +111 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/contribution.d.ts +21 -0
- package/dist/cli/commands/contribution.d.ts.map +1 -0
- package/dist/cli/commands/contribution.js +90 -0
- package/dist/cli/commands/contribution.js.map +1 -0
- package/dist/cli/commands/current.d.ts +18 -0
- package/dist/cli/commands/current.d.ts.map +1 -0
- package/dist/cli/commands/current.js +28 -0
- package/dist/cli/commands/current.js.map +1 -0
- package/dist/cli/commands/daemon.d.ts +36 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -0
- package/dist/cli/commands/daemon.js +223 -0
- package/dist/cli/commands/daemon.js.map +1 -0
- package/dist/cli/commands/dash.d.ts +23 -0
- package/dist/cli/commands/dash.d.ts.map +1 -0
- package/dist/cli/commands/dash.js +38 -0
- package/dist/cli/commands/dash.js.map +1 -0
- package/dist/cli/commands/decomposition.d.ts +13 -0
- package/dist/cli/commands/decomposition.d.ts.map +1 -0
- package/dist/cli/commands/decomposition.js +92 -0
- package/dist/cli/commands/decomposition.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +29 -0
- package/dist/cli/commands/delete.d.ts.map +1 -0
- package/dist/cli/commands/delete.js +55 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/deps.d.ts +45 -0
- package/dist/cli/commands/deps.d.ts.map +1 -0
- package/dist/cli/commands/deps.js +170 -0
- package/dist/cli/commands/deps.js.map +1 -0
- package/dist/cli/commands/detect-drift.d.ts +23 -0
- package/dist/cli/commands/detect-drift.d.ts.map +1 -0
- package/dist/cli/commands/detect-drift.js +440 -0
- package/dist/cli/commands/detect-drift.js.map +1 -0
- package/dist/cli/commands/detect.d.ts +3 -0
- package/dist/cli/commands/detect.d.ts.map +1 -0
- package/dist/cli/commands/detect.js +14 -0
- package/dist/cli/commands/detect.js.map +1 -0
- package/dist/cli/commands/diagnostics.d.ts +19 -0
- package/dist/cli/commands/diagnostics.d.ts.map +1 -0
- package/dist/cli/commands/diagnostics.js +109 -0
- package/dist/cli/commands/diagnostics.js.map +1 -0
- package/dist/cli/commands/docs.d.ts +25 -0
- package/dist/cli/commands/docs.d.ts.map +1 -0
- package/dist/cli/commands/docs.js +798 -0
- package/dist/cli/commands/docs.js.map +1 -0
- package/dist/cli/commands/doctor-projects.d.ts +101 -0
- package/dist/cli/commands/doctor-projects.d.ts.map +1 -0
- package/dist/cli/commands/doctor-projects.js +188 -0
- package/dist/cli/commands/doctor-projects.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +66 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +178 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/dynamic.d.ts +15 -0
- package/dist/cli/commands/dynamic.d.ts.map +1 -0
- package/dist/cli/commands/dynamic.js +21 -0
- package/dist/cli/commands/dynamic.js.map +1 -0
- package/dist/cli/commands/exists.d.ts +13 -0
- package/dist/cli/commands/exists.d.ts.map +1 -0
- package/dist/cli/commands/exists.js +40 -0
- package/dist/cli/commands/exists.js.map +1 -0
- package/dist/cli/commands/export-tasks.d.ts +46 -0
- package/dist/cli/commands/export-tasks.d.ts.map +1 -0
- package/dist/cli/commands/export-tasks.js +81 -0
- package/dist/cli/commands/export-tasks.js.map +1 -0
- package/dist/cli/commands/export.d.ts +35 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +68 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/find.d.ts +54 -0
- package/dist/cli/commands/find.d.ts.map +1 -0
- package/dist/cli/commands/find.js +92 -0
- package/dist/cli/commands/find.js.map +1 -0
- package/dist/cli/commands/gc.d.ts +25 -0
- package/dist/cli/commands/gc.d.ts.map +1 -0
- package/dist/cli/commands/gc.js +165 -0
- package/dist/cli/commands/gc.js.map +1 -0
- package/dist/cli/commands/generate-changelog.d.ts +30 -0
- package/dist/cli/commands/generate-changelog.d.ts.map +1 -0
- package/dist/cli/commands/generate-changelog.js +270 -0
- package/dist/cli/commands/generate-changelog.js.map +1 -0
- package/dist/cli/commands/grade.d.ts +13 -0
- package/dist/cli/commands/grade.d.ts.map +1 -0
- package/dist/cli/commands/grade.js +27 -0
- package/dist/cli/commands/grade.js.map +1 -0
- package/dist/cli/commands/history.d.ts +13 -0
- package/dist/cli/commands/history.d.ts.map +1 -0
- package/dist/cli/commands/history.js +65 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/import-tasks.d.ts +60 -0
- package/dist/cli/commands/import-tasks.d.ts.map +1 -0
- package/dist/cli/commands/import-tasks.js +83 -0
- package/dist/cli/commands/import-tasks.js.map +1 -0
- package/dist/cli/commands/import.d.ts +42 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +64 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/init.d.ts +65 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +122 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/inject.d.ts +41 -0
- package/dist/cli/commands/inject.d.ts.map +1 -0
- package/dist/cli/commands/inject.js +56 -0
- package/dist/cli/commands/inject.js.map +1 -0
- package/dist/cli/commands/install-global.d.ts +48 -0
- package/dist/cli/commands/install-global.d.ts.map +1 -0
- package/dist/cli/commands/install-global.js +104 -0
- package/dist/cli/commands/install-global.js.map +1 -0
- package/dist/cli/commands/intelligence.d.ts +21 -0
- package/dist/cli/commands/intelligence.d.ts.map +1 -0
- package/dist/cli/commands/intelligence.js +145 -0
- package/dist/cli/commands/intelligence.js.map +1 -0
- package/dist/cli/commands/issue.d.ts +23 -0
- package/dist/cli/commands/issue.d.ts.map +1 -0
- package/dist/cli/commands/issue.js +152 -0
- package/dist/cli/commands/issue.js.map +1 -0
- package/dist/cli/commands/labels.d.ts +21 -0
- package/dist/cli/commands/labels.d.ts.map +1 -0
- package/dist/cli/commands/labels.js +65 -0
- package/dist/cli/commands/labels.js.map +1 -0
- package/dist/cli/commands/lifecycle.d.ts +25 -0
- package/dist/cli/commands/lifecycle.d.ts.map +1 -0
- package/dist/cli/commands/lifecycle.js +221 -0
- package/dist/cli/commands/lifecycle.js.map +1 -0
- package/dist/cli/commands/list.d.ts +28 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +81 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/log.d.ts +36 -0
- package/dist/cli/commands/log.d.ts.map +1 -0
- package/dist/cli/commands/log.js +50 -0
- package/dist/cli/commands/log.js.map +1 -0
- package/dist/cli/commands/manifest.d.ts +15 -0
- package/dist/cli/commands/manifest.d.ts.map +1 -0
- package/dist/cli/commands/manifest.js +334 -0
- package/dist/cli/commands/manifest.js.map +1 -0
- package/dist/cli/commands/map.d.ts +25 -0
- package/dist/cli/commands/map.d.ts.map +1 -0
- package/dist/cli/commands/map.js +37 -0
- package/dist/cli/commands/map.js.map +1 -0
- package/dist/cli/commands/memory.d.ts +48 -0
- package/dist/cli/commands/memory.d.ts.map +1 -0
- package/dist/cli/commands/memory.js +2439 -0
- package/dist/cli/commands/memory.js.map +1 -0
- package/dist/cli/commands/migrate-claude-mem.d.ts +23 -0
- package/dist/cli/commands/migrate-claude-mem.d.ts.map +1 -0
- package/dist/cli/commands/migrate-claude-mem.js +181 -0
- package/dist/cli/commands/migrate-claude-mem.js.map +1 -0
- package/dist/cli/commands/next.d.ts +27 -0
- package/dist/cli/commands/next.d.ts.map +1 -0
- package/dist/cli/commands/next.js +40 -0
- package/dist/cli/commands/next.js.map +1 -0
- package/dist/cli/commands/nexus.d.ts +15 -0
- package/dist/cli/commands/nexus.d.ts.map +1 -0
- package/dist/cli/commands/nexus.js +3377 -0
- package/dist/cli/commands/nexus.js.map +1 -0
- package/dist/cli/commands/ops.d.ts +23 -0
- package/dist/cli/commands/ops.d.ts.map +1 -0
- package/dist/cli/commands/ops.js +35 -0
- package/dist/cli/commands/ops.js.map +1 -0
- package/dist/cli/commands/orchestrate.d.ts +48 -0
- package/dist/cli/commands/orchestrate.d.ts.map +1 -0
- package/dist/cli/commands/orchestrate.js +774 -0
- package/dist/cli/commands/orchestrate.js.map +1 -0
- package/dist/cli/commands/otel.d.ts +30 -0
- package/dist/cli/commands/otel.d.ts.map +1 -0
- package/dist/cli/commands/otel.js +193 -0
- package/dist/cli/commands/otel.js.map +1 -0
- package/dist/cli/commands/phase.d.ts +29 -0
- package/dist/cli/commands/phase.d.ts.map +1 -0
- package/dist/cli/commands/phase.js +189 -0
- package/dist/cli/commands/phase.js.map +1 -0
- package/dist/cli/commands/pivot.d.ts +34 -0
- package/dist/cli/commands/pivot.d.ts.map +1 -0
- package/dist/cli/commands/pivot.js +50 -0
- package/dist/cli/commands/pivot.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +17 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +27 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/playbook.d.ts +26 -0
- package/dist/cli/commands/playbook.d.ts.map +1 -0
- package/dist/cli/commands/playbook.js +220 -0
- package/dist/cli/commands/playbook.js.map +1 -0
- package/dist/cli/commands/promote.d.ts +19 -0
- package/dist/cli/commands/promote.d.ts.map +1 -0
- package/dist/cli/commands/promote.js +27 -0
- package/dist/cli/commands/promote.js.map +1 -0
- package/dist/cli/commands/provider.d.ts +23 -0
- package/dist/cli/commands/provider.d.ts.map +1 -0
- package/dist/cli/commands/provider.js +168 -0
- package/dist/cli/commands/provider.js.map +1 -0
- package/dist/cli/commands/reason.d.ts +18 -0
- package/dist/cli/commands/reason.d.ts.map +1 -0
- package/dist/cli/commands/reason.js +102 -0
- package/dist/cli/commands/reason.js.map +1 -0
- package/dist/cli/commands/reconcile.d.ts +35 -0
- package/dist/cli/commands/reconcile.d.ts.map +1 -0
- package/dist/cli/commands/reconcile.js +102 -0
- package/dist/cli/commands/reconcile.js.map +1 -0
- package/dist/cli/commands/refresh-memory.d.ts +16 -0
- package/dist/cli/commands/refresh-memory.d.ts.map +1 -0
- package/dist/cli/commands/refresh-memory.js +34 -0
- package/dist/cli/commands/refresh-memory.js.map +1 -0
- package/dist/cli/commands/relates.d.ts +19 -0
- package/dist/cli/commands/relates.d.ts.map +1 -0
- package/dist/cli/commands/relates.js +129 -0
- package/dist/cli/commands/relates.js.map +1 -0
- package/dist/cli/commands/release.d.ts +27 -0
- package/dist/cli/commands/release.d.ts.map +1 -0
- package/dist/cli/commands/release.js +300 -0
- package/dist/cli/commands/release.js.map +1 -0
- package/dist/cli/commands/remote.d.ts +49 -0
- package/dist/cli/commands/remote.d.ts.map +1 -0
- package/dist/cli/commands/remote.js +265 -0
- package/dist/cli/commands/remote.js.map +1 -0
- package/dist/cli/commands/reorder.d.ts +31 -0
- package/dist/cli/commands/reorder.d.ts.map +1 -0
- package/dist/cli/commands/reorder.js +57 -0
- package/dist/cli/commands/reorder.js.map +1 -0
- package/dist/cli/commands/reparent.d.ts +27 -0
- package/dist/cli/commands/reparent.d.ts.map +1 -0
- package/dist/cli/commands/reparent.js +36 -0
- package/dist/cli/commands/reparent.js.map +1 -0
- package/dist/cli/commands/req.d.ts +37 -0
- package/dist/cli/commands/req.d.ts.map +1 -0
- package/dist/cli/commands/req.js +121 -0
- package/dist/cli/commands/req.js.map +1 -0
- package/dist/cli/commands/research.d.ts +25 -0
- package/dist/cli/commands/research.d.ts.map +1 -0
- package/dist/cli/commands/research.js +327 -0
- package/dist/cli/commands/research.js.map +1 -0
- package/dist/cli/commands/restore.d.ts +64 -0
- package/dist/cli/commands/restore.d.ts.map +1 -0
- package/dist/cli/commands/restore.js +539 -0
- package/dist/cli/commands/restore.js.map +1 -0
- package/dist/cli/commands/revert.d.ts +79 -0
- package/dist/cli/commands/revert.d.ts.map +1 -0
- package/dist/cli/commands/revert.js +300 -0
- package/dist/cli/commands/revert.js.map +1 -0
- package/dist/cli/commands/roadmap.d.ts +29 -0
- package/dist/cli/commands/roadmap.d.ts.map +1 -0
- package/dist/cli/commands/roadmap.js +43 -0
- package/dist/cli/commands/roadmap.js.map +1 -0
- package/dist/cli/commands/safestop.d.ts +41 -0
- package/dist/cli/commands/safestop.d.ts.map +1 -0
- package/dist/cli/commands/safestop.js +62 -0
- package/dist/cli/commands/safestop.js.map +1 -0
- package/dist/cli/commands/schema.d.ts +44 -0
- package/dist/cli/commands/schema.d.ts.map +1 -0
- package/dist/cli/commands/schema.js +177 -0
- package/dist/cli/commands/schema.js.map +1 -0
- package/dist/cli/commands/self-update.d.ts +81 -0
- package/dist/cli/commands/self-update.d.ts.map +1 -0
- package/dist/cli/commands/self-update.js +483 -0
- package/dist/cli/commands/self-update.js.map +1 -0
- package/dist/cli/commands/sentient.d.ts +44 -0
- package/dist/cli/commands/sentient.d.ts.map +1 -0
- package/dist/cli/commands/sentient.js +687 -0
- package/dist/cli/commands/sentient.js.map +1 -0
- package/dist/cli/commands/sequence.d.ts +15 -0
- package/dist/cli/commands/sequence.d.ts.map +1 -0
- package/dist/cli/commands/sequence.js +68 -0
- package/dist/cli/commands/sequence.js.map +1 -0
- package/dist/cli/commands/session.d.ts +32 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +583 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/show.d.ts +21 -0
- package/dist/cli/commands/show.d.ts.map +1 -0
- package/dist/cli/commands/show.js +37 -0
- package/dist/cli/commands/show.js.map +1 -0
- package/dist/cli/commands/skills.d.ts +31 -0
- package/dist/cli/commands/skills.d.ts.map +1 -0
- package/dist/cli/commands/skills.js +303 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/commands/snapshot.d.ts +17 -0
- package/dist/cli/commands/snapshot.d.ts.map +1 -0
- package/dist/cli/commands/snapshot.js +95 -0
- package/dist/cli/commands/snapshot.js.map +1 -0
- package/dist/cli/commands/start.d.ts +21 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +32 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +30 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +71 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/sticky.d.ts +23 -0
- package/dist/cli/commands/sticky.d.ts.map +1 -0
- package/dist/cli/commands/sticky.js +315 -0
- package/dist/cli/commands/sticky.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +15 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +25 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +25 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +125 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/testing.d.ts +22 -0
- package/dist/cli/commands/testing.d.ts.map +1 -0
- package/dist/cli/commands/testing.js +111 -0
- package/dist/cli/commands/testing.js.map +1 -0
- package/dist/cli/commands/token.d.ts +22 -0
- package/dist/cli/commands/token.d.ts.map +1 -0
- package/dist/cli/commands/token.js +197 -0
- package/dist/cli/commands/token.js.map +1 -0
- package/dist/cli/commands/transcript.d.ts +32 -0
- package/dist/cli/commands/transcript.d.ts.map +1 -0
- package/dist/cli/commands/transcript.js +526 -0
- package/dist/cli/commands/transcript.js.map +1 -0
- package/dist/cli/commands/update.d.ts +164 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +234 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +76 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +154 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +83 -0
- package/dist/cli/commands/verify.d.ts.map +1 -0
- package/dist/cli/commands/verify.js +108 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/commands/web.d.ts +27 -0
- package/dist/cli/commands/web.d.ts.map +1 -0
- package/dist/cli/commands/web.js +414 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/field-context.d.ts +32 -0
- package/dist/cli/field-context.d.ts.map +1 -0
- package/dist/cli/field-context.js +47 -0
- package/dist/cli/field-context.js.map +1 -0
- package/dist/cli/format-context.d.ts +32 -0
- package/dist/cli/format-context.d.ts.map +1 -0
- package/dist/cli/format-context.js +50 -0
- package/dist/cli/format-context.js.map +1 -0
- package/dist/cli/help-renderer.d.ts +40 -0
- package/dist/cli/help-renderer.d.ts.map +1 -0
- package/dist/cli/help-renderer.js +325 -0
- package/dist/cli/help-renderer.js.map +1 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1561 -9748
- package/dist/cli/index.js.map +4 -4
- package/dist/cli/infer-files-via-gitnexus.d.ts +12 -0
- package/dist/cli/infer-files-via-gitnexus.d.ts.map +1 -0
- package/dist/cli/infer-files-via-gitnexus.js +12 -0
- package/dist/cli/infer-files-via-gitnexus.js.map +1 -0
- package/dist/cli/lib/did-you-mean.d.ts +30 -0
- package/dist/cli/lib/did-you-mean.d.ts.map +1 -0
- package/dist/cli/lib/did-you-mean.js +63 -0
- package/dist/cli/lib/did-you-mean.js.map +1 -0
- package/dist/cli/lib/registry-args.d.ts +36 -0
- package/dist/cli/lib/registry-args.d.ts.map +1 -0
- package/dist/cli/lib/registry-args.js +37 -0
- package/dist/cli/lib/registry-args.js.map +1 -0
- package/dist/cli/lib/subcommand-guard.d.ts +45 -0
- package/dist/cli/lib/subcommand-guard.d.ts.map +1 -0
- package/dist/cli/lib/subcommand-guard.js +55 -0
- package/dist/cli/lib/subcommand-guard.js.map +1 -0
- package/dist/cli/logger-bootstrap.d.ts +6 -0
- package/dist/cli/logger-bootstrap.d.ts.map +1 -0
- package/dist/cli/logger-bootstrap.js +10 -0
- package/dist/cli/logger-bootstrap.js.map +1 -0
- package/dist/cli/middleware/output-format.d.ts +30 -0
- package/dist/cli/middleware/output-format.d.ts.map +1 -0
- package/dist/cli/middleware/output-format.js +35 -0
- package/dist/cli/middleware/output-format.js.map +1 -0
- package/dist/cli/paths.d.ts +85 -0
- package/dist/cli/paths.d.ts.map +1 -0
- package/dist/cli/paths.js +108 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/progress.d.ts +89 -0
- package/dist/cli/progress.d.ts.map +1 -0
- package/dist/cli/progress.js +185 -0
- package/dist/cli/progress.js.map +1 -0
- package/dist/cli/renderers/colors.d.ts +32 -0
- package/dist/cli/renderers/colors.d.ts.map +1 -0
- package/dist/cli/renderers/colors.js +141 -0
- package/dist/cli/renderers/colors.js.map +1 -0
- package/dist/cli/renderers/error.d.ts +13 -0
- package/dist/cli/renderers/error.d.ts.map +1 -0
- package/dist/cli/renderers/error.js +42 -0
- package/dist/cli/renderers/error.js.map +1 -0
- package/dist/cli/renderers/index.d.ts +90 -0
- package/dist/cli/renderers/index.d.ts.map +1 -0
- package/dist/cli/renderers/index.js +268 -0
- package/dist/cli/renderers/index.js.map +1 -0
- package/dist/cli/renderers/lafs-validator.d.ts +91 -0
- package/dist/cli/renderers/lafs-validator.d.ts.map +1 -0
- package/dist/cli/renderers/lafs-validator.js +176 -0
- package/dist/cli/renderers/lafs-validator.js.map +1 -0
- package/dist/cli/renderers/normalizer.d.ts +21 -0
- package/dist/cli/renderers/normalizer.d.ts.map +1 -0
- package/dist/cli/renderers/normalizer.js +106 -0
- package/dist/cli/renderers/normalizer.js.map +1 -0
- package/dist/cli/renderers/system.d.ts +110 -0
- package/dist/cli/renderers/system.d.ts.map +1 -0
- package/dist/cli/renderers/system.js +662 -0
- package/dist/cli/renderers/system.js.map +1 -0
- package/dist/cli/renderers/tasks.d.ts +28 -0
- package/dist/cli/renderers/tasks.d.ts.map +1 -0
- package/dist/cli/renderers/tasks.js +306 -0
- package/dist/cli/renderers/tasks.js.map +1 -0
- package/dist/cli/tree-context.d.ts +53 -0
- package/dist/cli/tree-context.d.ts.map +1 -0
- package/dist/cli/tree-context.js +43 -0
- package/dist/cli/tree-context.js.map +1 -0
- package/dist/dispatch/adapters/cli.d.ts +67 -0
- package/dist/dispatch/adapters/cli.d.ts.map +1 -0
- package/dist/dispatch/adapters/cli.js +331 -0
- package/dist/dispatch/adapters/cli.js.map +1 -0
- package/dist/dispatch/adapters/typed.d.ts +362 -0
- package/dist/dispatch/adapters/typed.d.ts.map +1 -0
- package/dist/dispatch/adapters/typed.js +278 -0
- package/dist/dispatch/adapters/typed.js.map +1 -0
- package/dist/dispatch/context/session-context.d.ts +108 -0
- package/dist/dispatch/context/session-context.d.ts.map +1 -0
- package/dist/dispatch/context/session-context.js +111 -0
- package/dist/dispatch/context/session-context.js.map +1 -0
- package/dist/dispatch/dispatcher.d.ts +37 -0
- package/dist/dispatch/dispatcher.d.ts.map +1 -0
- package/dist/dispatch/dispatcher.js +172 -0
- package/dist/dispatch/dispatcher.js.map +1 -0
- package/dist/dispatch/domains/_base.d.ts +104 -0
- package/dist/dispatch/domains/_base.d.ts.map +1 -0
- package/dist/dispatch/domains/_base.js +147 -0
- package/dist/dispatch/domains/_base.js.map +1 -0
- package/dist/dispatch/domains/_meta.d.ts +23 -0
- package/dist/dispatch/domains/_meta.d.ts.map +1 -0
- package/dist/dispatch/domains/_meta.js +25 -0
- package/dist/dispatch/domains/_meta.js.map +1 -0
- package/dist/dispatch/domains/_routing.d.ts +8 -0
- package/dist/dispatch/domains/_routing.d.ts.map +1 -0
- package/dist/dispatch/domains/_routing.js +20 -0
- package/dist/dispatch/domains/_routing.js.map +1 -0
- package/dist/dispatch/domains/admin/smoke-provider.d.ts +54 -0
- package/dist/dispatch/domains/admin/smoke-provider.d.ts.map +1 -0
- package/dist/dispatch/domains/admin/smoke-provider.js +309 -0
- package/dist/dispatch/domains/admin/smoke-provider.js.map +1 -0
- package/dist/dispatch/domains/admin.d.ts +51 -0
- package/dist/dispatch/domains/admin.d.ts.map +1 -0
- package/dist/dispatch/domains/admin.js +1163 -0
- package/dist/dispatch/domains/admin.js.map +1 -0
- package/dist/dispatch/domains/check/canon.d.ts +65 -0
- package/dist/dispatch/domains/check/canon.d.ts.map +1 -0
- package/dist/dispatch/domains/check/canon.js +193 -0
- package/dist/dispatch/domains/check/canon.js.map +1 -0
- package/dist/dispatch/domains/check.d.ts +37 -0
- package/dist/dispatch/domains/check.d.ts.map +1 -0
- package/dist/dispatch/domains/check.js +562 -0
- package/dist/dispatch/domains/check.js.map +1 -0
- package/dist/dispatch/domains/conduit.d.ts +61 -0
- package/dist/dispatch/domains/conduit.d.ts.map +1 -0
- package/dist/dispatch/domains/conduit.js +609 -0
- package/dist/dispatch/domains/conduit.js.map +1 -0
- package/dist/dispatch/domains/diagnostics.d.ts +25 -0
- package/dist/dispatch/domains/diagnostics.d.ts.map +1 -0
- package/dist/dispatch/domains/diagnostics.js +82 -0
- package/dist/dispatch/domains/diagnostics.js.map +1 -0
- package/dist/dispatch/domains/docs.d.ts +63 -0
- package/dist/dispatch/domains/docs.d.ts.map +1 -0
- package/dist/dispatch/domains/docs.js +539 -0
- package/dist/dispatch/domains/docs.js.map +1 -0
- package/dist/dispatch/domains/index.d.ts +33 -0
- package/dist/dispatch/domains/index.d.ts.map +1 -0
- package/dist/dispatch/domains/index.js +58 -0
- package/dist/dispatch/domains/index.js.map +1 -0
- package/dist/dispatch/domains/intelligence.d.ts +26 -0
- package/dist/dispatch/domains/intelligence.d.ts.map +1 -0
- package/dist/dispatch/domains/intelligence.js +154 -0
- package/dist/dispatch/domains/intelligence.js.map +1 -0
- package/dist/dispatch/domains/ivtr.d.ts +182 -0
- package/dist/dispatch/domains/ivtr.d.ts.map +1 -0
- package/dist/dispatch/domains/ivtr.js +430 -0
- package/dist/dispatch/domains/ivtr.js.map +1 -0
- package/dist/dispatch/domains/memory.d.ts +22 -0
- package/dist/dispatch/domains/memory.d.ts.map +1 -0
- package/dist/dispatch/domains/memory.js +1281 -0
- package/dist/dispatch/domains/memory.js.map +1 -0
- package/dist/dispatch/domains/nexus.d.ts +78 -0
- package/dist/dispatch/domains/nexus.d.ts.map +1 -0
- package/dist/dispatch/domains/nexus.js +938 -0
- package/dist/dispatch/domains/nexus.js.map +1 -0
- package/dist/dispatch/domains/orchestrate.d.ts +307 -0
- package/dist/dispatch/domains/orchestrate.d.ts.map +1 -0
- package/dist/dispatch/domains/orchestrate.js +986 -0
- package/dist/dispatch/domains/orchestrate.js.map +1 -0
- package/dist/dispatch/domains/pipeline.d.ts +276 -0
- package/dist/dispatch/domains/pipeline.d.ts.map +1 -0
- package/dist/dispatch/domains/pipeline.js +689 -0
- package/dist/dispatch/domains/pipeline.js.map +1 -0
- package/dist/dispatch/domains/playbook.d.ts +131 -0
- package/dist/dispatch/domains/playbook.d.ts.map +1 -0
- package/dist/dispatch/domains/playbook.js +633 -0
- package/dist/dispatch/domains/playbook.js.map +1 -0
- package/dist/dispatch/domains/release.d.ts +97 -0
- package/dist/dispatch/domains/release.d.ts.map +1 -0
- package/dist/dispatch/domains/release.js +177 -0
- package/dist/dispatch/domains/release.js.map +1 -0
- package/dist/dispatch/domains/sentient.d.ts +60 -0
- package/dist/dispatch/domains/sentient.d.ts.map +1 -0
- package/dist/dispatch/domains/sentient.js +270 -0
- package/dist/dispatch/domains/sentient.js.map +1 -0
- package/dist/dispatch/domains/session.d.ts +49 -0
- package/dist/dispatch/domains/session.d.ts.map +1 -0
- package/dist/dispatch/domains/session.js +459 -0
- package/dist/dispatch/domains/session.js.map +1 -0
- package/dist/dispatch/domains/sticky.d.ts +82 -0
- package/dist/dispatch/domains/sticky.d.ts.map +1 -0
- package/dist/dispatch/domains/sticky.js +287 -0
- package/dist/dispatch/domains/sticky.js.map +1 -0
- package/dist/dispatch/domains/tasks.d.ts +58 -0
- package/dist/dispatch/domains/tasks.d.ts.map +1 -0
- package/dist/dispatch/domains/tasks.js +497 -0
- package/dist/dispatch/domains/tasks.js.map +1 -0
- package/dist/dispatch/domains/tools.d.ts +37 -0
- package/dist/dispatch/domains/tools.d.ts.map +1 -0
- package/dist/dispatch/domains/tools.js +481 -0
- package/dist/dispatch/domains/tools.js.map +1 -0
- package/dist/dispatch/engines/_error.d.ts +114 -0
- package/dist/dispatch/engines/_error.d.ts.map +1 -0
- package/dist/dispatch/engines/_error.js +290 -0
- package/dist/dispatch/engines/_error.js.map +1 -0
- package/dist/dispatch/engines/admin-engine.d.ts +386 -0
- package/dist/dispatch/engines/admin-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/admin-engine.js +270 -0
- package/dist/dispatch/engines/admin-engine.js.map +1 -0
- package/dist/dispatch/engines/code-engine.d.ts +14 -0
- package/dist/dispatch/engines/code-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/code-engine.js +14 -0
- package/dist/dispatch/engines/code-engine.js.map +1 -0
- package/dist/dispatch/engines/codebase-map-engine.d.ts +31 -0
- package/dist/dispatch/engines/codebase-map-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/codebase-map-engine.js +43 -0
- package/dist/dispatch/engines/codebase-map-engine.js.map +1 -0
- package/dist/dispatch/engines/config-engine.d.ts +14 -0
- package/dist/dispatch/engines/config-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/config-engine.js +14 -0
- package/dist/dispatch/engines/config-engine.js.map +1 -0
- package/dist/dispatch/engines/diagnostics-engine.d.ts +13 -0
- package/dist/dispatch/engines/diagnostics-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/diagnostics-engine.js +12 -0
- package/dist/dispatch/engines/diagnostics-engine.js.map +1 -0
- package/dist/dispatch/engines/hooks-engine.d.ts +13 -0
- package/dist/dispatch/engines/hooks-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/hooks-engine.js +12 -0
- package/dist/dispatch/engines/hooks-engine.js.map +1 -0
- package/dist/dispatch/engines/init-engine.d.ts +14 -0
- package/dist/dispatch/engines/init-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/init-engine.js +14 -0
- package/dist/dispatch/engines/init-engine.js.map +1 -0
- package/dist/dispatch/engines/lifecycle-engine.d.ts +13 -0
- package/dist/dispatch/engines/lifecycle-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/lifecycle-engine.js +12 -0
- package/dist/dispatch/engines/lifecycle-engine.js.map +1 -0
- package/dist/dispatch/engines/memory-engine.d.ts +10 -0
- package/dist/dispatch/engines/memory-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/memory-engine.js +10 -0
- package/dist/dispatch/engines/memory-engine.js.map +1 -0
- package/dist/dispatch/engines/nexus-engine.d.ts +603 -0
- package/dist/dispatch/engines/nexus-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/nexus-engine.js +1438 -0
- package/dist/dispatch/engines/nexus-engine.js.map +1 -0
- package/dist/dispatch/engines/orchestrate-engine.d.ts +252 -0
- package/dist/dispatch/engines/orchestrate-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/orchestrate-engine.js +1526 -0
- package/dist/dispatch/engines/orchestrate-engine.js.map +1 -0
- package/dist/dispatch/engines/pipeline-engine.d.ts +13 -0
- package/dist/dispatch/engines/pipeline-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/pipeline-engine.js +12 -0
- package/dist/dispatch/engines/pipeline-engine.js.map +1 -0
- package/dist/dispatch/engines/release-engine.d.ts +13 -0
- package/dist/dispatch/engines/release-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/release-engine.js +13 -0
- package/dist/dispatch/engines/release-engine.js.map +1 -0
- package/dist/dispatch/engines/session-engine.d.ts +15 -0
- package/dist/dispatch/engines/session-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/session-engine.js +12 -0
- package/dist/dispatch/engines/session-engine.js.map +1 -0
- package/dist/dispatch/engines/sticky-engine.d.ts +13 -0
- package/dist/dispatch/engines/sticky-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/sticky-engine.js +12 -0
- package/dist/dispatch/engines/sticky-engine.js.map +1 -0
- package/dist/dispatch/engines/system-engine.d.ts +543 -0
- package/dist/dispatch/engines/system-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/system-engine.js +1278 -0
- package/dist/dispatch/engines/system-engine.js.map +1 -0
- package/dist/dispatch/engines/task-engine.d.ts +1161 -0
- package/dist/dispatch/engines/task-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/task-engine.js +1599 -0
- package/dist/dispatch/engines/task-engine.js.map +1 -0
- package/dist/dispatch/engines/template-parser.d.ts +85 -0
- package/dist/dispatch/engines/template-parser.d.ts.map +1 -0
- package/dist/dispatch/engines/template-parser.js +114 -0
- package/dist/dispatch/engines/template-parser.js.map +1 -0
- package/dist/dispatch/engines/tools-engine.d.ts +13 -0
- package/dist/dispatch/engines/tools-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/tools-engine.js +12 -0
- package/dist/dispatch/engines/tools-engine.js.map +1 -0
- package/dist/dispatch/engines/validate-engine.d.ts +13 -0
- package/dist/dispatch/engines/validate-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/validate-engine.js +13 -0
- package/dist/dispatch/engines/validate-engine.js.map +1 -0
- package/dist/dispatch/index.d.ts +20 -0
- package/dist/dispatch/index.d.ts.map +1 -0
- package/dist/dispatch/index.js +19 -0
- package/dist/dispatch/index.js.map +1 -0
- package/dist/dispatch/lib/background-jobs.d.ts +162 -0
- package/dist/dispatch/lib/background-jobs.d.ts.map +1 -0
- package/dist/dispatch/lib/background-jobs.js +360 -0
- package/dist/dispatch/lib/background-jobs.js.map +1 -0
- package/dist/dispatch/lib/budget.d.ts +36 -0
- package/dist/dispatch/lib/budget.d.ts.map +1 -0
- package/dist/dispatch/lib/budget.js +109 -0
- package/dist/dispatch/lib/budget.js.map +1 -0
- package/dist/dispatch/lib/capability-matrix.d.ts +11 -0
- package/dist/dispatch/lib/capability-matrix.d.ts.map +1 -0
- package/dist/dispatch/lib/capability-matrix.js +10 -0
- package/dist/dispatch/lib/capability-matrix.js.map +1 -0
- package/dist/dispatch/lib/config-loader.d.ts +42 -0
- package/dist/dispatch/lib/config-loader.d.ts.map +1 -0
- package/dist/dispatch/lib/config-loader.js +218 -0
- package/dist/dispatch/lib/config-loader.js.map +1 -0
- package/dist/dispatch/lib/config.d.ts +11 -0
- package/dist/dispatch/lib/config.d.ts.map +1 -0
- package/dist/dispatch/lib/config.js +10 -0
- package/dist/dispatch/lib/config.js.map +1 -0
- package/dist/dispatch/lib/defaults.d.ts +115 -0
- package/dist/dispatch/lib/defaults.d.ts.map +1 -0
- package/dist/dispatch/lib/defaults.js +61 -0
- package/dist/dispatch/lib/defaults.js.map +1 -0
- package/dist/dispatch/lib/engine.d.ts +17 -0
- package/dist/dispatch/lib/engine.d.ts.map +1 -0
- package/dist/dispatch/lib/engine.js +36 -0
- package/dist/dispatch/lib/engine.js.map +1 -0
- package/dist/dispatch/lib/exit-codes.d.ts +35 -0
- package/dist/dispatch/lib/exit-codes.d.ts.map +1 -0
- package/dist/dispatch/lib/exit-codes.js +60 -0
- package/dist/dispatch/lib/exit-codes.js.map +1 -0
- package/dist/dispatch/lib/gateway-meta.d.ts +37 -0
- package/dist/dispatch/lib/gateway-meta.d.ts.map +1 -0
- package/dist/dispatch/lib/gateway-meta.js +50 -0
- package/dist/dispatch/lib/gateway-meta.js.map +1 -0
- package/dist/dispatch/lib/job-manager-accessor.d.ts +9 -0
- package/dist/dispatch/lib/job-manager-accessor.d.ts.map +1 -0
- package/dist/dispatch/lib/job-manager-accessor.js +13 -0
- package/dist/dispatch/lib/job-manager-accessor.js.map +1 -0
- package/dist/dispatch/lib/meta.d.ts +26 -0
- package/dist/dispatch/lib/meta.d.ts.map +1 -0
- package/dist/dispatch/lib/meta.js +37 -0
- package/dist/dispatch/lib/meta.js.map +1 -0
- package/dist/dispatch/lib/param-utils.d.ts +11 -0
- package/dist/dispatch/lib/param-utils.d.ts.map +1 -0
- package/dist/dispatch/lib/param-utils.js +10 -0
- package/dist/dispatch/lib/param-utils.js.map +1 -0
- package/dist/dispatch/lib/projections.d.ts +56 -0
- package/dist/dispatch/lib/projections.d.ts.map +1 -0
- package/dist/dispatch/lib/projections.js +65 -0
- package/dist/dispatch/lib/projections.js.map +1 -0
- package/dist/dispatch/lib/proto-envelope.d.ts +56 -0
- package/dist/dispatch/lib/proto-envelope.d.ts.map +1 -0
- package/dist/dispatch/lib/proto-envelope.js +17 -0
- package/dist/dispatch/lib/proto-envelope.js.map +1 -0
- package/dist/dispatch/lib/schema-utils.d.ts +39 -0
- package/dist/dispatch/lib/schema-utils.d.ts.map +1 -0
- package/dist/dispatch/lib/schema-utils.js +88 -0
- package/dist/dispatch/lib/schema-utils.js.map +1 -0
- package/dist/dispatch/lib/security.d.ts +11 -0
- package/dist/dispatch/lib/security.d.ts.map +1 -0
- package/dist/dispatch/lib/security.js +10 -0
- package/dist/dispatch/lib/security.js.map +1 -0
- package/dist/dispatch/middleware/audit.d.ts +23 -0
- package/dist/dispatch/middleware/audit.d.ts.map +1 -0
- package/dist/dispatch/middleware/audit.js +169 -0
- package/dist/dispatch/middleware/audit.js.map +1 -0
- package/dist/dispatch/middleware/field-filter.d.ts +25 -0
- package/dist/dispatch/middleware/field-filter.d.ts.map +1 -0
- package/dist/dispatch/middleware/field-filter.js +70 -0
- package/dist/dispatch/middleware/field-filter.js.map +1 -0
- package/dist/dispatch/middleware/pipeline.d.ts +33 -0
- package/dist/dispatch/middleware/pipeline.d.ts.map +1 -0
- package/dist/dispatch/middleware/pipeline.js +60 -0
- package/dist/dispatch/middleware/pipeline.js.map +1 -0
- package/dist/dispatch/middleware/projection.d.ts +35 -0
- package/dist/dispatch/middleware/projection.d.ts.map +1 -0
- package/dist/dispatch/middleware/projection.js +146 -0
- package/dist/dispatch/middleware/projection.js.map +1 -0
- package/dist/dispatch/middleware/protocol-enforcement.d.ts +30 -0
- package/dist/dispatch/middleware/protocol-enforcement.d.ts.map +1 -0
- package/dist/dispatch/middleware/protocol-enforcement.js +56 -0
- package/dist/dispatch/middleware/protocol-enforcement.js.map +1 -0
- package/dist/dispatch/middleware/rate-limiter.d.ts +72 -0
- package/dist/dispatch/middleware/rate-limiter.d.ts.map +1 -0
- package/dist/dispatch/middleware/rate-limiter.js +127 -0
- package/dist/dispatch/middleware/rate-limiter.js.map +1 -0
- package/dist/dispatch/middleware/sanitizer.d.ts +24 -0
- package/dist/dispatch/middleware/sanitizer.d.ts.map +1 -0
- package/dist/dispatch/middleware/sanitizer.js +56 -0
- package/dist/dispatch/middleware/sanitizer.js.map +1 -0
- package/dist/dispatch/middleware/session-resolver.d.ts +26 -0
- package/dist/dispatch/middleware/session-resolver.d.ts.map +1 -0
- package/dist/dispatch/middleware/session-resolver.js +65 -0
- package/dist/dispatch/middleware/session-resolver.js.map +1 -0
- package/dist/dispatch/middleware/telemetry.d.ts +21 -0
- package/dist/dispatch/middleware/telemetry.d.ts.map +1 -0
- package/dist/dispatch/middleware/telemetry.js +50 -0
- package/dist/dispatch/middleware/telemetry.js.map +1 -0
- package/dist/dispatch/middleware/verification-gates.d.ts +22 -0
- package/dist/dispatch/middleware/verification-gates.d.ts.map +1 -0
- package/dist/dispatch/middleware/verification-gates.js +59 -0
- package/dist/dispatch/middleware/verification-gates.js.map +1 -0
- package/dist/dispatch/registry.d.ts +91 -0
- package/dist/dispatch/registry.d.ts.map +1 -0
- package/dist/dispatch/registry.js +6430 -0
- package/dist/dispatch/registry.js.map +1 -0
- package/dist/dispatch/types.d.ts +150 -0
- package/dist/dispatch/types.d.ts.map +1 -0
- package/dist/dispatch/types.js +38 -0
- package/dist/dispatch/types.js.map +1 -0
- package/dist/migrations/2026-04-25-t991-parent-link-repair.d.ts +88 -0
- package/dist/migrations/2026-04-25-t991-parent-link-repair.d.ts.map +1 -0
- package/dist/migrations/2026-04-25-t991-parent-link-repair.js +76 -0
- package/dist/migrations/2026-04-25-t991-parent-link-repair.js.map +1 -0
- package/package.json +9 -9
|
@@ -0,0 +1,2439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI memory commands for BRAIN pattern and learning memory.
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* cleo memory store — store a pattern or learning
|
|
6
|
+
* cleo memory find — cross-table FTS5 search
|
|
7
|
+
* cleo memory stats — pattern + learning statistics
|
|
8
|
+
* cleo memory observe — save observation to brain.db
|
|
9
|
+
* cleo memory timeline — chronological context around anchor
|
|
10
|
+
* cleo memory fetch — full details for observation IDs
|
|
11
|
+
* cleo memory decision-find — search decisions
|
|
12
|
+
* cleo memory decision-store — store a decision
|
|
13
|
+
* cleo memory link — link a brain entry to a task
|
|
14
|
+
* cleo memory trace — BFS graph traversal
|
|
15
|
+
* cleo memory related — 1-hop graph neighbours
|
|
16
|
+
* cleo memory context — 360-degree node view
|
|
17
|
+
* cleo memory graph-stats — graph aggregate counts
|
|
18
|
+
* cleo memory graph-show — get graph node + edges
|
|
19
|
+
* cleo memory graph-neighbors — get neighbour nodes
|
|
20
|
+
* cleo memory graph-add — add node or edge
|
|
21
|
+
* cleo memory graph-remove — remove node or edge
|
|
22
|
+
* cleo memory reason-why — causal trace through task deps
|
|
23
|
+
* cleo memory reason-similar — semantically similar entries
|
|
24
|
+
* cleo memory search-hybrid — hybrid FTS5/vector/graph search
|
|
25
|
+
* cleo memory code-links — code ↔ memory connections
|
|
26
|
+
* cleo memory code-auto-link — auto-link brain to nexus
|
|
27
|
+
* cleo memory code-memories-for-code — memories referencing symbol
|
|
28
|
+
* cleo memory code-for-memory — code nodes for memory entry
|
|
29
|
+
* cleo memory consolidate — full consolidation pipeline
|
|
30
|
+
* cleo memory dream — full dream cycle (STDP)
|
|
31
|
+
* cleo memory reflect — LLM Observer + Reflector pipeline
|
|
32
|
+
* cleo memory dedup-scan — report/merge duplicate entries
|
|
33
|
+
* cleo memory import — migrate MEMORY.md files to brain.db
|
|
34
|
+
* cleo memory llm-status — LLM backend resolution status
|
|
35
|
+
* cleo memory verify — promote entry to verified=true
|
|
36
|
+
* cleo memory pending-verify — list unverified high-citation entries
|
|
37
|
+
* cleo memory tier — tier management (stats|promote|demote)
|
|
38
|
+
*
|
|
39
|
+
* @task T4770 T614 T629
|
|
40
|
+
* @epic T4763 T627
|
|
41
|
+
*/
|
|
42
|
+
import { createHash } from 'node:crypto';
|
|
43
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
44
|
+
import { homedir } from 'node:os';
|
|
45
|
+
import { join } from 'node:path';
|
|
46
|
+
import { getBrainDb, getBrainNativeDb, getProjectRoot, runConsolidation, triggerManualDream, } from '@cleocode/core/internal';
|
|
47
|
+
import { defineCommand, showUsage } from 'citty';
|
|
48
|
+
import { dispatchFromCli, dispatchRaw, handleRawError } from '../../dispatch/adapters/cli.js';
|
|
49
|
+
import { CLEO_DIR_NAME, MIGRATE_MEMORY_HASHES_JSON } from '../paths.js';
|
|
50
|
+
import { cliOutput } from '../renderers/index.js';
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Memory import helpers (T629 — provider-agnostic migration)
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
/**
|
|
55
|
+
* Parse YAML frontmatter from a markdown string.
|
|
56
|
+
* Supports simple `key: value` pairs only (no nested YAML).
|
|
57
|
+
*
|
|
58
|
+
* @param raw - Raw file content
|
|
59
|
+
* @returns Extracted frontmatter fields and body text
|
|
60
|
+
*/
|
|
61
|
+
function parseMemoryFileFrontmatter(raw) {
|
|
62
|
+
const lines = raw.split('\n');
|
|
63
|
+
if (!lines[0]?.trim().startsWith('---')) {
|
|
64
|
+
return { body: raw.trim() };
|
|
65
|
+
}
|
|
66
|
+
const endIdx = lines.slice(1).findIndex((l) => /^---\s*$/.test(l));
|
|
67
|
+
if (endIdx === -1) {
|
|
68
|
+
return { body: raw.trim() };
|
|
69
|
+
}
|
|
70
|
+
const fmLines = lines.slice(1, endIdx + 1);
|
|
71
|
+
const body = lines
|
|
72
|
+
.slice(endIdx + 2)
|
|
73
|
+
.join('\n')
|
|
74
|
+
.trim();
|
|
75
|
+
const fm = {};
|
|
76
|
+
for (const line of fmLines) {
|
|
77
|
+
const colonIdx = line.indexOf(':');
|
|
78
|
+
if (colonIdx === -1)
|
|
79
|
+
continue;
|
|
80
|
+
const key = line.slice(0, colonIdx).trim();
|
|
81
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
82
|
+
if (key && value)
|
|
83
|
+
fm[key] = value;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
name: fm['name'],
|
|
87
|
+
description: fm['description'],
|
|
88
|
+
type: fm['type'],
|
|
89
|
+
body,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Compute a 16-char hex content fingerprint for dedup.
|
|
94
|
+
*
|
|
95
|
+
* @param title - Entry title
|
|
96
|
+
* @param body - Entry body text
|
|
97
|
+
* @returns 16-char hex prefix of SHA-256 hash
|
|
98
|
+
*/
|
|
99
|
+
function memoryContentHash(title, body) {
|
|
100
|
+
return createHash('sha256').update(`${title}\n${body}`).digest('hex').slice(0, 16);
|
|
101
|
+
}
|
|
102
|
+
/** Load set of already-imported content hashes from the dedup state file. */
|
|
103
|
+
function loadImportHashes(stateFile) {
|
|
104
|
+
try {
|
|
105
|
+
if (!existsSync(stateFile))
|
|
106
|
+
return new Set();
|
|
107
|
+
const raw = readFileSync(stateFile, 'utf-8');
|
|
108
|
+
const parsed = JSON.parse(raw);
|
|
109
|
+
return new Set(parsed.hashes);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return new Set();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Persist updated set of imported hashes to the dedup state file. */
|
|
116
|
+
function saveImportHashes(stateFile, hashes) {
|
|
117
|
+
const dir = stateFile.slice(0, stateFile.lastIndexOf('/'));
|
|
118
|
+
if (!existsSync(dir))
|
|
119
|
+
mkdirSync(dir, { recursive: true });
|
|
120
|
+
writeFileSync(stateFile, JSON.stringify({ hashes: [...hashes] }, null, 2), 'utf-8');
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Subcommands
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
/** cleo memory store — store a pattern or learning to BRAIN memory */
|
|
126
|
+
const storeCommand = defineCommand({
|
|
127
|
+
meta: { name: 'store', description: 'Store a pattern or learning to BRAIN memory' },
|
|
128
|
+
args: {
|
|
129
|
+
type: {
|
|
130
|
+
type: 'string',
|
|
131
|
+
description: 'Memory type: pattern or learning',
|
|
132
|
+
required: true,
|
|
133
|
+
},
|
|
134
|
+
content: {
|
|
135
|
+
type: 'string',
|
|
136
|
+
description: 'Content of the memory entry',
|
|
137
|
+
required: true,
|
|
138
|
+
},
|
|
139
|
+
context: {
|
|
140
|
+
type: 'string',
|
|
141
|
+
description: 'Context in which the pattern/learning was observed',
|
|
142
|
+
},
|
|
143
|
+
source: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'Source of the learning',
|
|
146
|
+
},
|
|
147
|
+
'pattern-type': {
|
|
148
|
+
type: 'string',
|
|
149
|
+
description: 'Pattern type: workflow, blocker, success, failure, optimization',
|
|
150
|
+
},
|
|
151
|
+
impact: {
|
|
152
|
+
type: 'string',
|
|
153
|
+
description: 'Impact level: low, medium, high',
|
|
154
|
+
},
|
|
155
|
+
confidence: {
|
|
156
|
+
type: 'string',
|
|
157
|
+
description: 'Confidence score 0.0-1.0 (for learnings)',
|
|
158
|
+
},
|
|
159
|
+
actionable: {
|
|
160
|
+
type: 'boolean',
|
|
161
|
+
description: 'Mark learning as actionable',
|
|
162
|
+
},
|
|
163
|
+
'linked-task': {
|
|
164
|
+
type: 'string',
|
|
165
|
+
description: 'Task ID to link this memory to',
|
|
166
|
+
},
|
|
167
|
+
json: {
|
|
168
|
+
type: 'boolean',
|
|
169
|
+
description: 'Output as JSON',
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
async run({ args }) {
|
|
173
|
+
const memType = args.type;
|
|
174
|
+
if (memType === 'pattern') {
|
|
175
|
+
await dispatchFromCli('mutate', 'memory', 'pattern.store', {
|
|
176
|
+
type: args['pattern-type'] || 'workflow',
|
|
177
|
+
pattern: args.content,
|
|
178
|
+
context: args.context || 'Unspecified context',
|
|
179
|
+
impact: args.impact,
|
|
180
|
+
examples: args['linked-task'] ? [args['linked-task']] : [],
|
|
181
|
+
}, { command: 'memory', operation: 'memory.pattern.store' });
|
|
182
|
+
}
|
|
183
|
+
else if (memType === 'learning') {
|
|
184
|
+
await dispatchFromCli('mutate', 'memory', 'learning.store', {
|
|
185
|
+
insight: args.content,
|
|
186
|
+
source: args.source || 'manual',
|
|
187
|
+
confidence: args.confidence !== undefined ? parseFloat(args.confidence) : 0.5,
|
|
188
|
+
actionable: !!args.actionable,
|
|
189
|
+
applicableTypes: args['linked-task'] ? [args['linked-task']] : [],
|
|
190
|
+
}, { command: 'memory', operation: 'memory.learning.store' });
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
console.error(`Unknown memory type: ${memType}. Use 'pattern' or 'learning'.`);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
/** cleo memory find — search BRAIN memory (all tables, or filter by --type) */
|
|
199
|
+
const findCommand = defineCommand({
|
|
200
|
+
meta: {
|
|
201
|
+
name: 'find',
|
|
202
|
+
description: 'Search BRAIN memory (all tables, or filter by --type pattern|learning)',
|
|
203
|
+
},
|
|
204
|
+
args: {
|
|
205
|
+
query: {
|
|
206
|
+
type: 'positional',
|
|
207
|
+
description: 'Search query',
|
|
208
|
+
required: true,
|
|
209
|
+
},
|
|
210
|
+
type: {
|
|
211
|
+
type: 'string',
|
|
212
|
+
description: 'Filter by memory type: pattern or learning (default: all)',
|
|
213
|
+
},
|
|
214
|
+
'pattern-type': {
|
|
215
|
+
type: 'string',
|
|
216
|
+
description: 'Filter patterns by type: workflow, blocker, success, failure, optimization',
|
|
217
|
+
},
|
|
218
|
+
'min-confidence': {
|
|
219
|
+
type: 'string',
|
|
220
|
+
description: 'Minimum confidence for learnings',
|
|
221
|
+
},
|
|
222
|
+
actionable: {
|
|
223
|
+
type: 'boolean',
|
|
224
|
+
description: 'Only show actionable learnings',
|
|
225
|
+
},
|
|
226
|
+
limit: {
|
|
227
|
+
type: 'string',
|
|
228
|
+
description: 'Maximum results',
|
|
229
|
+
},
|
|
230
|
+
// T418: agent filter for per-agent mental model retrieval
|
|
231
|
+
agent: {
|
|
232
|
+
type: 'string',
|
|
233
|
+
description: 'Filter observations by agent provenance name (Wave 8 mental models)',
|
|
234
|
+
},
|
|
235
|
+
json: {
|
|
236
|
+
type: 'boolean',
|
|
237
|
+
description: 'Output as JSON',
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
async run({ args }) {
|
|
241
|
+
const query = args.query;
|
|
242
|
+
const memType = args.type;
|
|
243
|
+
if (memType === 'pattern') {
|
|
244
|
+
await dispatchFromCli('query', 'memory', 'pattern.find', {
|
|
245
|
+
query,
|
|
246
|
+
type: args['pattern-type'],
|
|
247
|
+
limit: args.limit !== undefined ? parseInt(args.limit, 10) : undefined,
|
|
248
|
+
}, { command: 'memory', operation: 'memory.find' });
|
|
249
|
+
}
|
|
250
|
+
else if (memType === 'learning') {
|
|
251
|
+
await dispatchFromCli('query', 'memory', 'learning.find', {
|
|
252
|
+
query,
|
|
253
|
+
minConfidence: args['min-confidence'] !== undefined ? parseFloat(args['min-confidence']) : undefined,
|
|
254
|
+
actionableOnly: !!args.actionable,
|
|
255
|
+
limit: args.limit !== undefined ? parseInt(args.limit, 10) : undefined,
|
|
256
|
+
}, { command: 'memory', operation: 'memory.find' });
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
await dispatchFromCli('query', 'memory', 'find', {
|
|
260
|
+
query,
|
|
261
|
+
limit: args.limit !== undefined ? parseInt(args.limit, 10) : undefined,
|
|
262
|
+
// T418: forward agent filter when provided
|
|
263
|
+
...(args.agent !== undefined && { agent: args.agent }),
|
|
264
|
+
}, { command: 'memory', operation: 'memory.find' });
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
/** cleo memory stats — show BRAIN memory statistics */
|
|
269
|
+
const statsCommand = defineCommand({
|
|
270
|
+
meta: { name: 'stats', description: 'Show BRAIN memory statistics' },
|
|
271
|
+
async run() {
|
|
272
|
+
// Output format is controlled by the global --json/--human flags (format-context),
|
|
273
|
+
// not by a per-command --json option (the global flag is resolved pre-dispatch).
|
|
274
|
+
const pResponse = await dispatchRaw('query', 'memory', 'pattern.find', {
|
|
275
|
+
query: '',
|
|
276
|
+
limit: 0,
|
|
277
|
+
});
|
|
278
|
+
const lResponse = await dispatchRaw('query', 'memory', 'learning.find', {
|
|
279
|
+
query: '',
|
|
280
|
+
limit: 0,
|
|
281
|
+
});
|
|
282
|
+
const result = {};
|
|
283
|
+
if (pResponse.success)
|
|
284
|
+
result['patterns'] = pResponse.data;
|
|
285
|
+
if (lResponse.success)
|
|
286
|
+
result['learnings'] = lResponse.data;
|
|
287
|
+
if (!pResponse.success && !lResponse.success) {
|
|
288
|
+
handleRawError(pResponse, { command: 'memory-stats', operation: 'memory.stats' });
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
cliOutput(result, { command: 'memory-stats', operation: 'memory.stats' });
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
/** cleo memory observe — save an observation to brain.db */
|
|
295
|
+
const observeCommand = defineCommand({
|
|
296
|
+
meta: {
|
|
297
|
+
name: 'observe',
|
|
298
|
+
description: 'Save an observation to brain.db — captures facts, decisions, and discoveries for cross-session memory',
|
|
299
|
+
},
|
|
300
|
+
args: {
|
|
301
|
+
text: {
|
|
302
|
+
type: 'positional',
|
|
303
|
+
description: 'Observation text',
|
|
304
|
+
required: true,
|
|
305
|
+
},
|
|
306
|
+
title: {
|
|
307
|
+
type: 'string',
|
|
308
|
+
description: 'Short title for the observation (defaults to first 120 chars of text)',
|
|
309
|
+
},
|
|
310
|
+
type: {
|
|
311
|
+
type: 'string',
|
|
312
|
+
description: 'Category: discovery (found something new), decision (choice made), bugfix (bug found/fixed), refactor (code restructured), feature (feature added), change (general change), diary (journal entry), session-summary (end-of-session recap auto-created by cleo session end)',
|
|
313
|
+
},
|
|
314
|
+
agent: {
|
|
315
|
+
type: 'string',
|
|
316
|
+
description: 'Name of the agent producing this observation (enables per-agent memory retrieval)',
|
|
317
|
+
},
|
|
318
|
+
'source-type': {
|
|
319
|
+
type: 'string',
|
|
320
|
+
description: 'How this observation was captured: manual (typed by human/agent), auto (lifecycle hook), transcript (extracted from session)',
|
|
321
|
+
},
|
|
322
|
+
attach: {
|
|
323
|
+
type: 'string',
|
|
324
|
+
description: 'SHA-256 of an attachment to link to this observation (comma-separated for multiple)',
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
async run({ args }) {
|
|
328
|
+
await dispatchFromCli('mutate', 'memory', 'observe', {
|
|
329
|
+
text: args.text,
|
|
330
|
+
title: args.title,
|
|
331
|
+
...(args.agent !== undefined && { agent: args.agent }),
|
|
332
|
+
...(args.type !== undefined && { type: args.type }),
|
|
333
|
+
sourceType: args['source-type'] ?? 'manual',
|
|
334
|
+
// T799: pass attachment refs
|
|
335
|
+
...(args.attach !== undefined && { attach: args.attach }),
|
|
336
|
+
}, { command: 'memory', operation: 'memory.observe' });
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
/** cleo memory timeline — show chronological context around an anchor observation ID */
|
|
340
|
+
const timelineCommand = defineCommand({
|
|
341
|
+
meta: {
|
|
342
|
+
name: 'timeline',
|
|
343
|
+
description: 'Show chronological context around an anchor observation ID',
|
|
344
|
+
},
|
|
345
|
+
args: {
|
|
346
|
+
// Output format is controlled by the global --json/--human flags (format-context).
|
|
347
|
+
anchor: {
|
|
348
|
+
type: 'positional',
|
|
349
|
+
description: 'Anchor observation ID',
|
|
350
|
+
required: true,
|
|
351
|
+
},
|
|
352
|
+
before: {
|
|
353
|
+
type: 'string',
|
|
354
|
+
description: 'Number of entries before anchor',
|
|
355
|
+
},
|
|
356
|
+
after: {
|
|
357
|
+
type: 'string',
|
|
358
|
+
description: 'Number of entries after anchor',
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
async run({ args }) {
|
|
362
|
+
await dispatchFromCli('query', 'memory', 'timeline', {
|
|
363
|
+
anchor: args.anchor,
|
|
364
|
+
depthBefore: args.before !== undefined ? parseInt(args.before, 10) : undefined,
|
|
365
|
+
depthAfter: args.after !== undefined ? parseInt(args.after, 10) : undefined,
|
|
366
|
+
}, { command: 'memory-timeline', operation: 'memory.timeline' });
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
/** cleo memory fetch — fetch full details for specific observation IDs */
|
|
370
|
+
const fetchCommand = defineCommand({
|
|
371
|
+
meta: { name: 'fetch', description: 'Fetch full details for specific observation IDs' },
|
|
372
|
+
args: {
|
|
373
|
+
// Note: citty doesn't support variadic positional args, so we accept a single
|
|
374
|
+
// positional and split on commas/spaces to support: `cleo memory fetch ID1,ID2`
|
|
375
|
+
// Output format is controlled by the global --json/--human flags (format-context).
|
|
376
|
+
ids: {
|
|
377
|
+
type: 'positional',
|
|
378
|
+
description: 'Comma- or space-separated observation IDs',
|
|
379
|
+
required: true,
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
async run({ args }) {
|
|
383
|
+
const ids = args.ids
|
|
384
|
+
.split(/[,\s]+/)
|
|
385
|
+
.map((s) => s.trim())
|
|
386
|
+
.filter(Boolean);
|
|
387
|
+
await dispatchFromCli('query', 'memory', 'fetch', { ids }, { command: 'memory-fetch', operation: 'memory.fetch' });
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
/** cleo memory decision-find — search decisions stored in brain.db */
|
|
391
|
+
const decisionFindCommand = defineCommand({
|
|
392
|
+
meta: { name: 'decision-find', description: 'Search decisions stored in brain.db' },
|
|
393
|
+
args: {
|
|
394
|
+
query: {
|
|
395
|
+
type: 'positional',
|
|
396
|
+
description: 'Search query',
|
|
397
|
+
required: false,
|
|
398
|
+
},
|
|
399
|
+
limit: {
|
|
400
|
+
type: 'string',
|
|
401
|
+
description: 'Maximum results',
|
|
402
|
+
},
|
|
403
|
+
json: {
|
|
404
|
+
type: 'boolean',
|
|
405
|
+
description: 'Output as JSON',
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
async run({ args }) {
|
|
409
|
+
await dispatchFromCli('query', 'memory', 'decision.find', {
|
|
410
|
+
query: args.query ?? '',
|
|
411
|
+
limit: args.limit !== undefined ? parseInt(args.limit, 10) : undefined,
|
|
412
|
+
}, { command: 'memory', operation: 'memory.decision.find' });
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
/** cleo memory decision-store — store a decision to brain.db */
|
|
416
|
+
const decisionStoreCommand = defineCommand({
|
|
417
|
+
meta: { name: 'decision-store', description: 'Store a decision to brain.db' },
|
|
418
|
+
args: {
|
|
419
|
+
decision: {
|
|
420
|
+
type: 'string',
|
|
421
|
+
description: 'The decision that was made',
|
|
422
|
+
required: true,
|
|
423
|
+
},
|
|
424
|
+
rationale: {
|
|
425
|
+
type: 'string',
|
|
426
|
+
description: 'Rationale behind the decision',
|
|
427
|
+
required: true,
|
|
428
|
+
},
|
|
429
|
+
alternatives: {
|
|
430
|
+
type: 'string',
|
|
431
|
+
description: 'Alternatives that were considered',
|
|
432
|
+
},
|
|
433
|
+
'linked-task': {
|
|
434
|
+
type: 'string',
|
|
435
|
+
description: 'Task ID to associate with this decision',
|
|
436
|
+
},
|
|
437
|
+
json: {
|
|
438
|
+
type: 'boolean',
|
|
439
|
+
description: 'Output as JSON',
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
async run({ args }) {
|
|
443
|
+
await dispatchFromCli('mutate', 'memory', 'decision.store', {
|
|
444
|
+
decision: args.decision,
|
|
445
|
+
rationale: args.rationale,
|
|
446
|
+
...(args.alternatives !== undefined && { alternatives: args.alternatives }),
|
|
447
|
+
...(args['linked-task'] !== undefined && { taskId: args['linked-task'] }),
|
|
448
|
+
}, { command: 'memory', operation: 'memory.decision.store' });
|
|
449
|
+
},
|
|
450
|
+
});
|
|
451
|
+
/** cleo memory link — link a brain entry to a task */
|
|
452
|
+
const linkCommand = defineCommand({
|
|
453
|
+
meta: { name: 'link', description: 'Link a brain entry to a task' },
|
|
454
|
+
args: {
|
|
455
|
+
taskId: {
|
|
456
|
+
type: 'positional',
|
|
457
|
+
description: 'Task ID',
|
|
458
|
+
required: true,
|
|
459
|
+
},
|
|
460
|
+
entryId: {
|
|
461
|
+
type: 'positional',
|
|
462
|
+
description: 'Brain entry ID',
|
|
463
|
+
required: true,
|
|
464
|
+
},
|
|
465
|
+
json: {
|
|
466
|
+
type: 'boolean',
|
|
467
|
+
description: 'Output as JSON',
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
async run({ args }) {
|
|
471
|
+
await dispatchFromCli('mutate', 'memory', 'link', { taskId: args.taskId, entryId: args.entryId }, { command: 'memory', operation: 'memory.link' });
|
|
472
|
+
},
|
|
473
|
+
});
|
|
474
|
+
/** cleo memory trace — BFS traversal of the brain knowledge graph from a seed node */
|
|
475
|
+
const traceCommand = defineCommand({
|
|
476
|
+
meta: {
|
|
477
|
+
name: 'trace',
|
|
478
|
+
description: 'BFS traversal of the brain knowledge graph from a seed node',
|
|
479
|
+
},
|
|
480
|
+
args: {
|
|
481
|
+
nodeId: {
|
|
482
|
+
type: 'positional',
|
|
483
|
+
description: 'Seed node ID',
|
|
484
|
+
required: true,
|
|
485
|
+
},
|
|
486
|
+
depth: {
|
|
487
|
+
type: 'string',
|
|
488
|
+
description: 'Maximum traversal depth (default: 3)',
|
|
489
|
+
},
|
|
490
|
+
json: {
|
|
491
|
+
type: 'boolean',
|
|
492
|
+
description: 'Output as JSON',
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
async run({ args }) {
|
|
496
|
+
await dispatchFromCli('query', 'memory', 'graph.trace', {
|
|
497
|
+
nodeId: args.nodeId,
|
|
498
|
+
...(args.depth !== undefined && { maxDepth: parseInt(args.depth, 10) }),
|
|
499
|
+
}, { command: 'memory-trace', operation: 'memory.graph.trace' });
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
/** cleo memory related — return immediate (1-hop) neighbours of a brain graph node */
|
|
503
|
+
const relatedCommand = defineCommand({
|
|
504
|
+
meta: {
|
|
505
|
+
name: 'related',
|
|
506
|
+
description: 'Return immediate (1-hop) neighbours of a brain graph node',
|
|
507
|
+
},
|
|
508
|
+
args: {
|
|
509
|
+
nodeId: {
|
|
510
|
+
type: 'positional',
|
|
511
|
+
description: 'Node ID',
|
|
512
|
+
required: true,
|
|
513
|
+
},
|
|
514
|
+
type: {
|
|
515
|
+
type: 'string',
|
|
516
|
+
description: 'Filter by edge type (e.g. applies_to, supports, derived_from)',
|
|
517
|
+
},
|
|
518
|
+
json: {
|
|
519
|
+
type: 'boolean',
|
|
520
|
+
description: 'Output as JSON',
|
|
521
|
+
},
|
|
522
|
+
},
|
|
523
|
+
async run({ args }) {
|
|
524
|
+
await dispatchFromCli('query', 'memory', 'graph.related', {
|
|
525
|
+
nodeId: args.nodeId,
|
|
526
|
+
...(args.type !== undefined && { edgeType: args.type }),
|
|
527
|
+
}, { command: 'memory-related', operation: 'memory.graph.related' });
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
/** cleo memory context — 360-degree context view of a brain graph node */
|
|
531
|
+
const contextCommand = defineCommand({
|
|
532
|
+
meta: {
|
|
533
|
+
name: 'context',
|
|
534
|
+
description: '360-degree context view of a brain graph node: node + all edges + neighbours',
|
|
535
|
+
},
|
|
536
|
+
args: {
|
|
537
|
+
nodeId: {
|
|
538
|
+
type: 'positional',
|
|
539
|
+
description: 'Node ID',
|
|
540
|
+
required: true,
|
|
541
|
+
},
|
|
542
|
+
json: {
|
|
543
|
+
type: 'boolean',
|
|
544
|
+
description: 'Output as JSON',
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
async run({ args }) {
|
|
548
|
+
await dispatchFromCli('query', 'memory', 'graph.context', { nodeId: args.nodeId }, { command: 'memory-context', operation: 'memory.graph.context' });
|
|
549
|
+
},
|
|
550
|
+
});
|
|
551
|
+
/** cleo memory graph-stats — show brain knowledge graph statistics */
|
|
552
|
+
const graphStatsCommand = defineCommand({
|
|
553
|
+
meta: {
|
|
554
|
+
name: 'graph-stats',
|
|
555
|
+
description: 'Show brain knowledge graph statistics: node and edge counts by type',
|
|
556
|
+
},
|
|
557
|
+
args: {
|
|
558
|
+
json: {
|
|
559
|
+
type: 'boolean',
|
|
560
|
+
description: 'Output as JSON',
|
|
561
|
+
},
|
|
562
|
+
},
|
|
563
|
+
async run() {
|
|
564
|
+
await dispatchFromCli('query', 'memory', 'graph.stats', {}, { command: 'memory-graph-stats', operation: 'memory.graph.stats' });
|
|
565
|
+
},
|
|
566
|
+
});
|
|
567
|
+
/** cleo memory graph-show — get a PageIndex graph node and its edges */
|
|
568
|
+
const graphShowCommand = defineCommand({
|
|
569
|
+
meta: { name: 'graph-show', description: 'Get a PageIndex graph node and its edges' },
|
|
570
|
+
args: {
|
|
571
|
+
nodeId: {
|
|
572
|
+
type: 'positional',
|
|
573
|
+
description: 'Node ID',
|
|
574
|
+
required: true,
|
|
575
|
+
},
|
|
576
|
+
json: {
|
|
577
|
+
type: 'boolean',
|
|
578
|
+
description: 'Output as JSON',
|
|
579
|
+
},
|
|
580
|
+
},
|
|
581
|
+
async run({ args }) {
|
|
582
|
+
await dispatchFromCli('query', 'memory', 'graph.show', { nodeId: args.nodeId }, { command: 'memory', operation: 'memory.graph.show' });
|
|
583
|
+
},
|
|
584
|
+
});
|
|
585
|
+
/** cleo memory graph-neighbors — get neighbor nodes from the PageIndex graph */
|
|
586
|
+
const graphNeighborsCommand = defineCommand({
|
|
587
|
+
meta: {
|
|
588
|
+
name: 'graph-neighbors',
|
|
589
|
+
description: 'Get neighbor nodes from the PageIndex graph',
|
|
590
|
+
},
|
|
591
|
+
args: {
|
|
592
|
+
nodeId: {
|
|
593
|
+
type: 'positional',
|
|
594
|
+
description: 'Node ID',
|
|
595
|
+
required: true,
|
|
596
|
+
},
|
|
597
|
+
depth: {
|
|
598
|
+
type: 'string',
|
|
599
|
+
description: 'Traversal depth',
|
|
600
|
+
},
|
|
601
|
+
limit: {
|
|
602
|
+
type: 'string',
|
|
603
|
+
description: 'Maximum neighbors',
|
|
604
|
+
},
|
|
605
|
+
json: {
|
|
606
|
+
type: 'boolean',
|
|
607
|
+
description: 'Output as JSON',
|
|
608
|
+
},
|
|
609
|
+
},
|
|
610
|
+
async run({ args }) {
|
|
611
|
+
await dispatchFromCli('query', 'memory', 'graph.neighbors', {
|
|
612
|
+
nodeId: args.nodeId,
|
|
613
|
+
...(args.depth !== undefined && { depth: parseInt(args.depth, 10) }),
|
|
614
|
+
...(args.limit !== undefined && { limit: parseInt(args.limit, 10) }),
|
|
615
|
+
}, { command: 'memory', operation: 'memory.graph.neighbors' });
|
|
616
|
+
},
|
|
617
|
+
});
|
|
618
|
+
/** cleo memory graph-add — add a node or edge to the PageIndex graph */
|
|
619
|
+
const graphAddCommand = defineCommand({
|
|
620
|
+
meta: { name: 'graph-add', description: 'Add a node or edge to the PageIndex graph' },
|
|
621
|
+
args: {
|
|
622
|
+
'node-id': {
|
|
623
|
+
type: 'string',
|
|
624
|
+
description: 'Node ID to add',
|
|
625
|
+
},
|
|
626
|
+
'node-type': {
|
|
627
|
+
type: 'string',
|
|
628
|
+
description: 'Node type (e.g. concept, task, file)',
|
|
629
|
+
},
|
|
630
|
+
label: {
|
|
631
|
+
type: 'string',
|
|
632
|
+
description: 'Label for the node',
|
|
633
|
+
},
|
|
634
|
+
from: {
|
|
635
|
+
type: 'string',
|
|
636
|
+
description: 'Source node ID for an edge',
|
|
637
|
+
},
|
|
638
|
+
to: {
|
|
639
|
+
type: 'string',
|
|
640
|
+
description: 'Target node ID for an edge',
|
|
641
|
+
},
|
|
642
|
+
'edge-type': {
|
|
643
|
+
type: 'string',
|
|
644
|
+
description: 'Edge relationship type',
|
|
645
|
+
},
|
|
646
|
+
json: {
|
|
647
|
+
type: 'boolean',
|
|
648
|
+
description: 'Output as JSON',
|
|
649
|
+
},
|
|
650
|
+
},
|
|
651
|
+
async run({ args }) {
|
|
652
|
+
await dispatchFromCli('mutate', 'memory', 'graph.add', {
|
|
653
|
+
...(args['node-id'] !== undefined && { nodeId: args['node-id'] }),
|
|
654
|
+
...(args['node-type'] !== undefined && { nodeType: args['node-type'] }),
|
|
655
|
+
...(args.label !== undefined && { label: args.label }),
|
|
656
|
+
...(args.from !== undefined && { fromId: args.from }),
|
|
657
|
+
...(args.to !== undefined && { toId: args.to }),
|
|
658
|
+
...(args['edge-type'] !== undefined && { edgeType: args['edge-type'] }),
|
|
659
|
+
}, { command: 'memory', operation: 'memory.graph.add' });
|
|
660
|
+
},
|
|
661
|
+
});
|
|
662
|
+
/** cleo memory graph-remove — remove a node or edge from the PageIndex graph */
|
|
663
|
+
const graphRemoveCommand = defineCommand({
|
|
664
|
+
meta: { name: 'graph-remove', description: 'Remove a node or edge from the PageIndex graph' },
|
|
665
|
+
args: {
|
|
666
|
+
'node-id': {
|
|
667
|
+
type: 'string',
|
|
668
|
+
description: 'Node ID to remove',
|
|
669
|
+
},
|
|
670
|
+
from: {
|
|
671
|
+
type: 'string',
|
|
672
|
+
description: 'Source node ID of the edge to remove',
|
|
673
|
+
},
|
|
674
|
+
to: {
|
|
675
|
+
type: 'string',
|
|
676
|
+
description: 'Target node ID of the edge to remove',
|
|
677
|
+
},
|
|
678
|
+
json: {
|
|
679
|
+
type: 'boolean',
|
|
680
|
+
description: 'Output as JSON',
|
|
681
|
+
},
|
|
682
|
+
},
|
|
683
|
+
async run({ args }) {
|
|
684
|
+
await dispatchFromCli('mutate', 'memory', 'graph.remove', {
|
|
685
|
+
...(args['node-id'] !== undefined && { nodeId: args['node-id'] }),
|
|
686
|
+
...(args.from !== undefined && { fromId: args.from }),
|
|
687
|
+
...(args.to !== undefined && { toId: args.to }),
|
|
688
|
+
}, { command: 'memory', operation: 'memory.graph.remove' });
|
|
689
|
+
},
|
|
690
|
+
});
|
|
691
|
+
/** cleo memory reason-why — causal trace through task dependency chains */
|
|
692
|
+
const reasonWhyCommand = defineCommand({
|
|
693
|
+
meta: { name: 'reason-why', description: 'Causal trace through task dependency chains' },
|
|
694
|
+
args: {
|
|
695
|
+
taskId: {
|
|
696
|
+
type: 'positional',
|
|
697
|
+
description: 'Task ID',
|
|
698
|
+
required: true,
|
|
699
|
+
},
|
|
700
|
+
depth: {
|
|
701
|
+
type: 'string',
|
|
702
|
+
description: 'Maximum trace depth',
|
|
703
|
+
},
|
|
704
|
+
json: {
|
|
705
|
+
type: 'boolean',
|
|
706
|
+
description: 'Output as JSON',
|
|
707
|
+
},
|
|
708
|
+
},
|
|
709
|
+
async run({ args }) {
|
|
710
|
+
await dispatchFromCli('query', 'memory', 'reason.why', {
|
|
711
|
+
taskId: args.taskId,
|
|
712
|
+
...(args.depth !== undefined && { depth: parseInt(args.depth, 10) }),
|
|
713
|
+
}, { command: 'memory', operation: 'memory.reason.why' });
|
|
714
|
+
},
|
|
715
|
+
});
|
|
716
|
+
/** cleo memory reason-similar — find semantically similar brain entries */
|
|
717
|
+
const reasonSimilarCommand = defineCommand({
|
|
718
|
+
meta: { name: 'reason-similar', description: 'Find semantically similar brain entries' },
|
|
719
|
+
args: {
|
|
720
|
+
entryId: {
|
|
721
|
+
type: 'positional',
|
|
722
|
+
description: 'Entry ID',
|
|
723
|
+
required: true,
|
|
724
|
+
},
|
|
725
|
+
limit: {
|
|
726
|
+
type: 'string',
|
|
727
|
+
description: 'Maximum results',
|
|
728
|
+
},
|
|
729
|
+
json: {
|
|
730
|
+
type: 'boolean',
|
|
731
|
+
description: 'Output as JSON',
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
async run({ args }) {
|
|
735
|
+
await dispatchFromCli('query', 'memory', 'reason.similar', {
|
|
736
|
+
entryId: args.entryId,
|
|
737
|
+
...(args.limit !== undefined && { limit: parseInt(args.limit, 10) }),
|
|
738
|
+
}, { command: 'memory', operation: 'memory.reason.similar' });
|
|
739
|
+
},
|
|
740
|
+
});
|
|
741
|
+
/** cleo memory search-hybrid — hybrid search across FTS5, vector, and graph indexes */
|
|
742
|
+
const searchHybridCommand = defineCommand({
|
|
743
|
+
meta: {
|
|
744
|
+
name: 'search-hybrid',
|
|
745
|
+
description: 'Hybrid search across FTS5, vector, and graph indexes',
|
|
746
|
+
},
|
|
747
|
+
args: {
|
|
748
|
+
query: {
|
|
749
|
+
type: 'positional',
|
|
750
|
+
description: 'Search query',
|
|
751
|
+
required: true,
|
|
752
|
+
},
|
|
753
|
+
limit: {
|
|
754
|
+
type: 'string',
|
|
755
|
+
description: 'Maximum results',
|
|
756
|
+
},
|
|
757
|
+
json: {
|
|
758
|
+
type: 'boolean',
|
|
759
|
+
description: 'Output as JSON',
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
async run({ args }) {
|
|
763
|
+
await dispatchFromCli('query', 'memory', 'search.hybrid', {
|
|
764
|
+
query: args.query,
|
|
765
|
+
...(args.limit !== undefined && { limit: parseInt(args.limit, 10) }),
|
|
766
|
+
}, { command: 'memory', operation: 'memory.search.hybrid' });
|
|
767
|
+
},
|
|
768
|
+
});
|
|
769
|
+
/** cleo memory code-links — show all code ↔ memory connections */
|
|
770
|
+
const codeLinksCommand = defineCommand({
|
|
771
|
+
meta: {
|
|
772
|
+
name: 'code-links',
|
|
773
|
+
description: 'Show code ↔ memory connections (code_reference edges between brain and nexus)',
|
|
774
|
+
},
|
|
775
|
+
args: {
|
|
776
|
+
limit: {
|
|
777
|
+
type: 'string',
|
|
778
|
+
description: 'Maximum entries to return (default 100)',
|
|
779
|
+
},
|
|
780
|
+
json: {
|
|
781
|
+
type: 'boolean',
|
|
782
|
+
description: 'Output as JSON',
|
|
783
|
+
},
|
|
784
|
+
},
|
|
785
|
+
async run({ args }) {
|
|
786
|
+
await dispatchFromCli('query', 'memory', 'code.links', {
|
|
787
|
+
...(args.limit !== undefined && { limit: parseInt(args.limit, 10) }),
|
|
788
|
+
}, { command: 'memory', operation: 'memory.code.links' });
|
|
789
|
+
},
|
|
790
|
+
});
|
|
791
|
+
/** cleo memory code-auto-link — scan brain nodes and auto-link to nexus */
|
|
792
|
+
const codeAutoLinkCommand = defineCommand({
|
|
793
|
+
meta: {
|
|
794
|
+
name: 'code-auto-link',
|
|
795
|
+
description: 'Scan brain memory nodes for entity references and auto-link to nexus code nodes',
|
|
796
|
+
},
|
|
797
|
+
args: {
|
|
798
|
+
json: {
|
|
799
|
+
type: 'boolean',
|
|
800
|
+
description: 'Output as JSON',
|
|
801
|
+
},
|
|
802
|
+
},
|
|
803
|
+
async run() {
|
|
804
|
+
await dispatchFromCli('mutate', 'memory', 'code.auto-link', {}, { command: 'memory', operation: 'memory.code.auto-link' });
|
|
805
|
+
},
|
|
806
|
+
});
|
|
807
|
+
/** cleo memory code-memories-for-code — find memories that reference a code symbol */
|
|
808
|
+
const codeMemoriesForCodeCommand = defineCommand({
|
|
809
|
+
meta: {
|
|
810
|
+
name: 'code-memories-for-code',
|
|
811
|
+
description: 'Find brain memory nodes that reference a given nexus code symbol',
|
|
812
|
+
},
|
|
813
|
+
args: {
|
|
814
|
+
symbol: {
|
|
815
|
+
type: 'positional',
|
|
816
|
+
description: 'Code symbol name',
|
|
817
|
+
required: true,
|
|
818
|
+
},
|
|
819
|
+
json: {
|
|
820
|
+
type: 'boolean',
|
|
821
|
+
description: 'Output as JSON',
|
|
822
|
+
},
|
|
823
|
+
},
|
|
824
|
+
async run({ args }) {
|
|
825
|
+
await dispatchFromCli('query', 'memory', 'code.memories-for-code', { symbol: args.symbol }, { command: 'memory', operation: 'memory.code.memories-for-code' });
|
|
826
|
+
},
|
|
827
|
+
});
|
|
828
|
+
/** cleo memory code-for-memory — find code nodes referenced by a memory entry */
|
|
829
|
+
const codeForMemoryCommand = defineCommand({
|
|
830
|
+
meta: {
|
|
831
|
+
name: 'code-for-memory',
|
|
832
|
+
description: 'Find nexus code nodes referenced by a given brain memory entry',
|
|
833
|
+
},
|
|
834
|
+
args: {
|
|
835
|
+
memoryId: {
|
|
836
|
+
type: 'positional',
|
|
837
|
+
description: 'Memory entry ID',
|
|
838
|
+
required: true,
|
|
839
|
+
},
|
|
840
|
+
json: {
|
|
841
|
+
type: 'boolean',
|
|
842
|
+
description: 'Output as JSON',
|
|
843
|
+
},
|
|
844
|
+
},
|
|
845
|
+
async run({ args }) {
|
|
846
|
+
await dispatchFromCli('query', 'memory', 'code.for-memory', { memoryId: args.memoryId }, { command: 'memory', operation: 'memory.code.for-memory' });
|
|
847
|
+
},
|
|
848
|
+
});
|
|
849
|
+
/** cleo memory consolidate — run the full brain consolidation pipeline on demand */
|
|
850
|
+
const consolidateCommand = defineCommand({
|
|
851
|
+
meta: {
|
|
852
|
+
name: 'consolidate',
|
|
853
|
+
description: 'Run the full brain consolidation pipeline: dedup, quality recompute, tier promotion, ' +
|
|
854
|
+
'contradiction detection, soft eviction, graph strengthening, summary generation. ' +
|
|
855
|
+
'Equivalent to the session-end sleep-time consolidation but triggered on demand.',
|
|
856
|
+
},
|
|
857
|
+
args: {
|
|
858
|
+
json: {
|
|
859
|
+
type: 'boolean',
|
|
860
|
+
description: 'Output results as JSON',
|
|
861
|
+
},
|
|
862
|
+
},
|
|
863
|
+
async run({ args }) {
|
|
864
|
+
const root = getProjectRoot();
|
|
865
|
+
const isJson = !!args.json;
|
|
866
|
+
if (!isJson) {
|
|
867
|
+
console.log('Running memory consolidation (including tier promotion)...');
|
|
868
|
+
}
|
|
869
|
+
try {
|
|
870
|
+
const result = await runConsolidation(root);
|
|
871
|
+
if (isJson) {
|
|
872
|
+
console.log(JSON.stringify({
|
|
873
|
+
success: true,
|
|
874
|
+
data: result,
|
|
875
|
+
meta: {
|
|
876
|
+
operation: 'memory.consolidate',
|
|
877
|
+
timestamp: new Date().toISOString(),
|
|
878
|
+
},
|
|
879
|
+
}, null, 2));
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
// Human-readable output
|
|
883
|
+
console.log('\nConsolidation complete.');
|
|
884
|
+
console.log(` Deduplicated: ${result.deduplicated}`);
|
|
885
|
+
console.log(` Quality recomp: ${result.qualityRecomputed}`);
|
|
886
|
+
console.log(` Tier promoted: ${result.tierPromotions.promoted.length} entries promoted`);
|
|
887
|
+
console.log(` Tier evicted: ${result.tierPromotions.evicted.length} entries evicted`);
|
|
888
|
+
console.log(` Contradictions: ${result.contradictions}`);
|
|
889
|
+
console.log(` Soft evicted: ${result.softEvicted}`);
|
|
890
|
+
console.log(` Edges strength: ${result.edgesStrengthened}`);
|
|
891
|
+
console.log(` Summaries gen: ${result.summariesGenerated}`);
|
|
892
|
+
if (result.graphLinksCreated !== undefined) {
|
|
893
|
+
console.log(` Graph links: ${result.graphLinksCreated}`);
|
|
894
|
+
}
|
|
895
|
+
if (result.tierPromotions.promoted.length > 0) {
|
|
896
|
+
console.log('\nTier promotions:');
|
|
897
|
+
for (const p of result.tierPromotions.promoted) {
|
|
898
|
+
console.log(` [${p.table}] ${p.id}: ${p.fromTier} → ${p.toTier} (${p.reason})`);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
catch (err) {
|
|
903
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
904
|
+
if (isJson) {
|
|
905
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
906
|
+
}
|
|
907
|
+
else {
|
|
908
|
+
console.error(`Memory consolidation failed: ${message}`);
|
|
909
|
+
}
|
|
910
|
+
process.exit(1);
|
|
911
|
+
}
|
|
912
|
+
},
|
|
913
|
+
});
|
|
914
|
+
/** cleo memory dream — manually trigger the full dream cycle including STDP plasticity (T628) */
|
|
915
|
+
const dreamCommand = defineCommand({
|
|
916
|
+
meta: {
|
|
917
|
+
name: 'dream',
|
|
918
|
+
description: 'Manually trigger the full auto-dream cycle: consolidation pipeline including ' +
|
|
919
|
+
'R-STDP reward backfill (Step 9a), STDP plasticity (Step 9b), and homeostatic ' +
|
|
920
|
+
'decay (Step 9c). Equivalent to autonomous nightly consolidation but ' +
|
|
921
|
+
'triggered on demand. Idempotent — safe to run multiple times.',
|
|
922
|
+
},
|
|
923
|
+
args: {
|
|
924
|
+
json: {
|
|
925
|
+
type: 'boolean',
|
|
926
|
+
description: 'Output results as JSON',
|
|
927
|
+
},
|
|
928
|
+
},
|
|
929
|
+
async run({ args }) {
|
|
930
|
+
const root = getProjectRoot();
|
|
931
|
+
const isJson = !!args.json;
|
|
932
|
+
if (!isJson) {
|
|
933
|
+
console.log('Triggering dream cycle (full consolidation including STDP plasticity)...');
|
|
934
|
+
}
|
|
935
|
+
try {
|
|
936
|
+
const result = await triggerManualDream(root);
|
|
937
|
+
if (isJson) {
|
|
938
|
+
console.log(JSON.stringify({
|
|
939
|
+
success: true,
|
|
940
|
+
data: result,
|
|
941
|
+
meta: {
|
|
942
|
+
operation: 'memory.dream',
|
|
943
|
+
timestamp: new Date().toISOString(),
|
|
944
|
+
},
|
|
945
|
+
}, null, 2));
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
// Human-readable output
|
|
949
|
+
console.log('\nDream cycle complete.');
|
|
950
|
+
console.log(` Deduplicated: ${result.deduplicated}`);
|
|
951
|
+
console.log(` Quality recomp: ${result.qualityRecomputed}`);
|
|
952
|
+
console.log(` Tier promoted: ${result.tierPromotions.promoted.length} entries promoted`);
|
|
953
|
+
console.log(` Tier evicted: ${result.tierPromotions.evicted.length} entries evicted`);
|
|
954
|
+
console.log(` Contradictions: ${result.contradictions}`);
|
|
955
|
+
console.log(` Soft evicted: ${result.softEvicted}`);
|
|
956
|
+
console.log(` Edges strength: ${result.edgesStrengthened}`);
|
|
957
|
+
console.log(` Summaries gen: ${result.summariesGenerated}`);
|
|
958
|
+
if (result.graphLinksCreated !== undefined) {
|
|
959
|
+
console.log(` Graph links: ${result.graphLinksCreated}`);
|
|
960
|
+
}
|
|
961
|
+
if (result.rewardBackfilled !== undefined) {
|
|
962
|
+
console.log(` Reward backfill: ${result.rewardBackfilled.rowsLabeled} labeled, ` +
|
|
963
|
+
`${result.rewardBackfilled.rowsSkipped} skipped`);
|
|
964
|
+
}
|
|
965
|
+
if (result.stdpPlasticity !== undefined) {
|
|
966
|
+
console.log(` STDP plasticity: ${result.stdpPlasticity.ltpEvents} LTP, ` +
|
|
967
|
+
`${result.stdpPlasticity.ltdEvents} LTD, ` +
|
|
968
|
+
`${result.stdpPlasticity.edgesCreated} edges created`);
|
|
969
|
+
}
|
|
970
|
+
if (result.homeostaticDecay !== undefined) {
|
|
971
|
+
console.log(` Decay/pruning: ${result.homeostaticDecay.edgesDecayed} decayed, ` +
|
|
972
|
+
`${result.homeostaticDecay.edgesPruned} pruned`);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
catch (err) {
|
|
976
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
977
|
+
if (isJson) {
|
|
978
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
console.error(`Dream cycle failed: ${message}`);
|
|
982
|
+
}
|
|
983
|
+
process.exit(1);
|
|
984
|
+
}
|
|
985
|
+
},
|
|
986
|
+
});
|
|
987
|
+
/** cleo memory reflect — manually trigger the LLM Observer + Reflector pipeline (T745) */
|
|
988
|
+
const reflectCommand = defineCommand({
|
|
989
|
+
meta: {
|
|
990
|
+
name: 'reflect',
|
|
991
|
+
description: 'Manually trigger the LLM Observer + Reflector pipeline for the most recent session. ' +
|
|
992
|
+
'Observer compresses session observations; Reflector synthesizes patterns and learnings. ' +
|
|
993
|
+
'Requires ANTHROPIC_API_KEY to be set.',
|
|
994
|
+
},
|
|
995
|
+
args: {
|
|
996
|
+
session: {
|
|
997
|
+
type: 'string',
|
|
998
|
+
description: 'Run against a specific session ID (default: most recent session)',
|
|
999
|
+
},
|
|
1000
|
+
json: {
|
|
1001
|
+
type: 'boolean',
|
|
1002
|
+
description: 'Output results as JSON',
|
|
1003
|
+
},
|
|
1004
|
+
},
|
|
1005
|
+
async run({ args }) {
|
|
1006
|
+
const root = getProjectRoot();
|
|
1007
|
+
const isJson = !!args.json;
|
|
1008
|
+
if (!isJson) {
|
|
1009
|
+
console.log('Running Observer + Reflector pipeline...');
|
|
1010
|
+
}
|
|
1011
|
+
try {
|
|
1012
|
+
const { runObserver, runReflector } = await import('@cleocode/core/internal');
|
|
1013
|
+
const observerResult = await runObserver(root, args.session, {
|
|
1014
|
+
thresholdOverride: 1,
|
|
1015
|
+
});
|
|
1016
|
+
const reflectorResult = await runReflector(root, args.session);
|
|
1017
|
+
const data = {
|
|
1018
|
+
observer: {
|
|
1019
|
+
ran: observerResult.ran,
|
|
1020
|
+
stored: observerResult.stored,
|
|
1021
|
+
compressedIds: observerResult.compressedIds,
|
|
1022
|
+
},
|
|
1023
|
+
reflector: {
|
|
1024
|
+
ran: reflectorResult.ran,
|
|
1025
|
+
patternsStored: reflectorResult.patternsStored,
|
|
1026
|
+
learningsStored: reflectorResult.learningsStored,
|
|
1027
|
+
supersededIds: reflectorResult.supersededIds,
|
|
1028
|
+
},
|
|
1029
|
+
};
|
|
1030
|
+
if (isJson) {
|
|
1031
|
+
console.log(JSON.stringify({
|
|
1032
|
+
success: true,
|
|
1033
|
+
data,
|
|
1034
|
+
meta: {
|
|
1035
|
+
operation: 'memory.reflect',
|
|
1036
|
+
timestamp: new Date().toISOString(),
|
|
1037
|
+
},
|
|
1038
|
+
}, null, 2));
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
console.log('\nReflection complete.');
|
|
1042
|
+
if (!observerResult.ran) {
|
|
1043
|
+
console.log(' Observer: skipped (no API key, disabled in config, or no observations)');
|
|
1044
|
+
}
|
|
1045
|
+
else {
|
|
1046
|
+
console.log(` Observer: compressed ${observerResult.stored} notes`);
|
|
1047
|
+
console.log(` Source IDs: ${observerResult.compressedIds.length} observations`);
|
|
1048
|
+
}
|
|
1049
|
+
if (!reflectorResult.ran) {
|
|
1050
|
+
console.log(' Reflector: skipped (no API key, disabled in config, or < 3 observations)');
|
|
1051
|
+
}
|
|
1052
|
+
else {
|
|
1053
|
+
console.log(` Reflector: ${reflectorResult.patternsStored} patterns, ${reflectorResult.learningsStored} learnings`);
|
|
1054
|
+
if (reflectorResult.supersededIds.length > 0) {
|
|
1055
|
+
console.log(` Superseded: ${reflectorResult.supersededIds.length} observations`);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
catch (err) {
|
|
1060
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1061
|
+
if (isJson) {
|
|
1062
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
1063
|
+
}
|
|
1064
|
+
else {
|
|
1065
|
+
console.error(`Reflect failed: ${message}`);
|
|
1066
|
+
}
|
|
1067
|
+
process.exit(1);
|
|
1068
|
+
}
|
|
1069
|
+
},
|
|
1070
|
+
});
|
|
1071
|
+
/** cleo memory dedup-scan — scan brain.db for potential duplicate entries (T745) */
|
|
1072
|
+
const dedupScanCommand = defineCommand({
|
|
1073
|
+
meta: {
|
|
1074
|
+
name: 'dedup-scan',
|
|
1075
|
+
description: 'Scan brain.db for potential duplicate entries by content-hash and keyword similarity. ' +
|
|
1076
|
+
'Reports duplicates per table without modifying any data. ' +
|
|
1077
|
+
'Use --apply to merge confirmed duplicates via the consolidation pipeline.',
|
|
1078
|
+
},
|
|
1079
|
+
args: {
|
|
1080
|
+
apply: {
|
|
1081
|
+
type: 'boolean',
|
|
1082
|
+
description: 'Run full consolidation to merge duplicates (calls cleo memory consolidate internally)',
|
|
1083
|
+
},
|
|
1084
|
+
json: {
|
|
1085
|
+
type: 'boolean',
|
|
1086
|
+
description: 'Output results as JSON',
|
|
1087
|
+
},
|
|
1088
|
+
},
|
|
1089
|
+
async run({ args }) {
|
|
1090
|
+
const root = getProjectRoot();
|
|
1091
|
+
const isJson = !!args.json;
|
|
1092
|
+
if (!isJson) {
|
|
1093
|
+
console.log('Scanning brain.db for duplicate entries...');
|
|
1094
|
+
}
|
|
1095
|
+
try {
|
|
1096
|
+
const { getBrainDb: getBrainDbInner, getBrainNativeDb: getBrainNativeDbInner } = await import('@cleocode/core/internal');
|
|
1097
|
+
await getBrainDbInner(root);
|
|
1098
|
+
const nativeDb = getBrainNativeDbInner();
|
|
1099
|
+
if (!nativeDb) {
|
|
1100
|
+
const msg = 'brain.db is unavailable';
|
|
1101
|
+
if (isJson) {
|
|
1102
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1103
|
+
}
|
|
1104
|
+
else {
|
|
1105
|
+
console.error(msg);
|
|
1106
|
+
}
|
|
1107
|
+
process.exit(1);
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
// Scan each table for content-hash duplicates
|
|
1111
|
+
const tables = [
|
|
1112
|
+
{ name: 'brain_observations', hashCol: 'content_hash', labelCol: 'title' },
|
|
1113
|
+
{ name: 'brain_decisions', hashCol: 'content_hash', labelCol: 'decision' },
|
|
1114
|
+
{ name: 'brain_patterns', hashCol: 'content_hash', labelCol: 'pattern' },
|
|
1115
|
+
{ name: 'brain_learnings', hashCol: 'content_hash', labelCol: 'insight' },
|
|
1116
|
+
];
|
|
1117
|
+
const groups = [];
|
|
1118
|
+
for (const t of tables) {
|
|
1119
|
+
let dupRows;
|
|
1120
|
+
try {
|
|
1121
|
+
dupRows = nativeDb
|
|
1122
|
+
.prepare(`SELECT ${t.hashCol} AS hash, COUNT(*) AS cnt
|
|
1123
|
+
FROM ${t.name}
|
|
1124
|
+
WHERE ${t.hashCol} IS NOT NULL
|
|
1125
|
+
AND invalid_at IS NULL
|
|
1126
|
+
GROUP BY ${t.hashCol}
|
|
1127
|
+
HAVING cnt > 1
|
|
1128
|
+
ORDER BY cnt DESC
|
|
1129
|
+
LIMIT 20`)
|
|
1130
|
+
.all();
|
|
1131
|
+
}
|
|
1132
|
+
catch {
|
|
1133
|
+
dupRows = [];
|
|
1134
|
+
}
|
|
1135
|
+
for (const row of dupRows) {
|
|
1136
|
+
let sampleRows;
|
|
1137
|
+
try {
|
|
1138
|
+
sampleRows = nativeDb
|
|
1139
|
+
.prepare(`SELECT id, COALESCE(${t.labelCol}, id) AS label
|
|
1140
|
+
FROM ${t.name}
|
|
1141
|
+
WHERE ${t.hashCol} = ?
|
|
1142
|
+
AND invalid_at IS NULL
|
|
1143
|
+
LIMIT 3`)
|
|
1144
|
+
.all(row.hash);
|
|
1145
|
+
}
|
|
1146
|
+
catch {
|
|
1147
|
+
sampleRows = [];
|
|
1148
|
+
}
|
|
1149
|
+
groups.push({
|
|
1150
|
+
table: t.name,
|
|
1151
|
+
hash: row.hash,
|
|
1152
|
+
count: row.cnt,
|
|
1153
|
+
samples: sampleRows.map((r) => `${r.id}: ${String(r.label).slice(0, 80)}`),
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
const totalDups = groups.reduce((sum, g) => sum + (g.count - 1), 0);
|
|
1158
|
+
if (isJson) {
|
|
1159
|
+
console.log(JSON.stringify({
|
|
1160
|
+
success: true,
|
|
1161
|
+
data: {
|
|
1162
|
+
totalDuplicateRows: totalDups,
|
|
1163
|
+
groups,
|
|
1164
|
+
applied: false,
|
|
1165
|
+
},
|
|
1166
|
+
meta: {
|
|
1167
|
+
operation: 'memory.dedup-scan',
|
|
1168
|
+
timestamp: new Date().toISOString(),
|
|
1169
|
+
},
|
|
1170
|
+
}, null, 2));
|
|
1171
|
+
}
|
|
1172
|
+
else {
|
|
1173
|
+
if (groups.length === 0) {
|
|
1174
|
+
console.log('No hash-duplicate entries found.');
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
console.log(`\nFound ${totalDups} duplicate rows across ${groups.length} groups:`);
|
|
1178
|
+
for (const g of groups) {
|
|
1179
|
+
console.log(`\n [${g.table}] hash=${g.hash.slice(0, 12)}... (${g.count} copies)`);
|
|
1180
|
+
for (const s of g.samples) {
|
|
1181
|
+
console.log(` - ${s}`);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
// Optionally merge duplicates via the consolidation pipeline
|
|
1187
|
+
if (args.apply) {
|
|
1188
|
+
if (!isJson)
|
|
1189
|
+
console.log('\nApplying — running consolidation to merge duplicates...');
|
|
1190
|
+
const { runConsolidation: runConsolidationInner } = await import('@cleocode/core/internal');
|
|
1191
|
+
const result = await runConsolidationInner(root);
|
|
1192
|
+
if (isJson) {
|
|
1193
|
+
// Reprint with applied=true
|
|
1194
|
+
console.log(JSON.stringify({
|
|
1195
|
+
success: true,
|
|
1196
|
+
data: {
|
|
1197
|
+
totalDuplicateRows: totalDups,
|
|
1198
|
+
groups,
|
|
1199
|
+
applied: true,
|
|
1200
|
+
consolidation: { deduplicated: result.deduplicated },
|
|
1201
|
+
},
|
|
1202
|
+
meta: {
|
|
1203
|
+
operation: 'memory.dedup-scan',
|
|
1204
|
+
timestamp: new Date().toISOString(),
|
|
1205
|
+
},
|
|
1206
|
+
}, null, 2));
|
|
1207
|
+
}
|
|
1208
|
+
else {
|
|
1209
|
+
console.log(`Consolidation merged ${result.deduplicated} duplicate entries.`);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
catch (err) {
|
|
1214
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1215
|
+
if (isJson) {
|
|
1216
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
1217
|
+
}
|
|
1218
|
+
else {
|
|
1219
|
+
console.error(`Dedup scan failed: ${message}`);
|
|
1220
|
+
}
|
|
1221
|
+
process.exit(1);
|
|
1222
|
+
}
|
|
1223
|
+
},
|
|
1224
|
+
});
|
|
1225
|
+
/** cleo memory import — migrate MEMORY.md files to brain.db (T629 provider-agnostic) */
|
|
1226
|
+
const importCommand = defineCommand({
|
|
1227
|
+
meta: {
|
|
1228
|
+
name: 'import',
|
|
1229
|
+
description: 'Import memory files from a provider-specific directory (e.g. ~/.claude/projects/*/memory/) into brain.db. ' +
|
|
1230
|
+
'Enables provider-agnostic memory via CLEO CLI instead of Claude Code MEMORY.md.',
|
|
1231
|
+
},
|
|
1232
|
+
args: {
|
|
1233
|
+
from: {
|
|
1234
|
+
type: 'string',
|
|
1235
|
+
description: 'Source directory containing *.md memory files ' +
|
|
1236
|
+
'(default: ~/.claude/projects/-mnt-projects-cleocode/memory)',
|
|
1237
|
+
},
|
|
1238
|
+
'dry-run': {
|
|
1239
|
+
type: 'boolean',
|
|
1240
|
+
description: 'Print what would be imported without writing to brain.db',
|
|
1241
|
+
},
|
|
1242
|
+
json: {
|
|
1243
|
+
type: 'boolean',
|
|
1244
|
+
description: 'Output results as JSON',
|
|
1245
|
+
},
|
|
1246
|
+
},
|
|
1247
|
+
async run({ args }) {
|
|
1248
|
+
const sourceDir = args.from ?? join(homedir(), '.claude', 'projects', '-mnt-projects-cleocode', 'memory');
|
|
1249
|
+
const isDryRun = !!args['dry-run'];
|
|
1250
|
+
const isJson = !!args.json;
|
|
1251
|
+
const projectRoot = getProjectRoot();
|
|
1252
|
+
const stateFile = join(projectRoot, CLEO_DIR_NAME, MIGRATE_MEMORY_HASHES_JSON);
|
|
1253
|
+
if (!existsSync(sourceDir)) {
|
|
1254
|
+
const msg = `Source directory not found: ${sourceDir}`;
|
|
1255
|
+
if (isJson) {
|
|
1256
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1257
|
+
}
|
|
1258
|
+
else {
|
|
1259
|
+
console.error(msg);
|
|
1260
|
+
}
|
|
1261
|
+
process.exit(1);
|
|
1262
|
+
}
|
|
1263
|
+
const files = readdirSync(sourceDir)
|
|
1264
|
+
.filter((f) => f.endsWith('.md') && f !== 'MEMORY.md')
|
|
1265
|
+
.map((f) => join(sourceDir, f));
|
|
1266
|
+
const importedHashes = isDryRun ? new Set() : loadImportHashes(stateFile);
|
|
1267
|
+
const stats = { total: files.length, imported: 0, skipped: 0, errors: 0 };
|
|
1268
|
+
const importedEntries = [];
|
|
1269
|
+
const skippedEntries = [];
|
|
1270
|
+
const errorEntries = [];
|
|
1271
|
+
if (!isJson) {
|
|
1272
|
+
console.log(`Importing memory from: ${sourceDir}`);
|
|
1273
|
+
console.log(`Files found: ${files.length}`);
|
|
1274
|
+
if (isDryRun)
|
|
1275
|
+
console.log('Mode: DRY RUN');
|
|
1276
|
+
console.log('');
|
|
1277
|
+
}
|
|
1278
|
+
for (const filePath of files) {
|
|
1279
|
+
const fileName = filePath.split('/').pop() ?? filePath;
|
|
1280
|
+
try {
|
|
1281
|
+
const raw = readFileSync(filePath, 'utf-8');
|
|
1282
|
+
if (!raw.trim()) {
|
|
1283
|
+
stats.skipped++;
|
|
1284
|
+
skippedEntries.push({ file: fileName, reason: 'empty file' });
|
|
1285
|
+
continue;
|
|
1286
|
+
}
|
|
1287
|
+
const { name, description, type, body } = parseMemoryFileFrontmatter(raw);
|
|
1288
|
+
const title = name ?? fileName.replace(/\.md$/, '').replace(/-/g, ' ');
|
|
1289
|
+
const bodyParts = [description, body].filter(Boolean);
|
|
1290
|
+
const fullText = bodyParts.join('\n\n').trim();
|
|
1291
|
+
if (!fullText) {
|
|
1292
|
+
stats.skipped++;
|
|
1293
|
+
skippedEntries.push({ file: fileName, reason: 'empty body' });
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
const hash = memoryContentHash(title, fullText);
|
|
1297
|
+
if (!isDryRun && importedHashes.has(hash)) {
|
|
1298
|
+
stats.skipped++;
|
|
1299
|
+
skippedEntries.push({ file: fileName, reason: `already imported (hash: ${hash})` });
|
|
1300
|
+
if (!isJson)
|
|
1301
|
+
console.log(` [SKIP] ${fileName}`);
|
|
1302
|
+
continue;
|
|
1303
|
+
}
|
|
1304
|
+
const entryType = type ?? 'project';
|
|
1305
|
+
if (!isJson) {
|
|
1306
|
+
const prefix = isDryRun ? '[DRY-RUN]' : '[IMPORT]';
|
|
1307
|
+
console.log(` ${prefix} ${fileName} (type: ${entryType})`);
|
|
1308
|
+
}
|
|
1309
|
+
if (!isDryRun) {
|
|
1310
|
+
// Route by frontmatter type
|
|
1311
|
+
if (entryType === 'feedback') {
|
|
1312
|
+
// Feedback → learning
|
|
1313
|
+
await dispatchFromCli('mutate', 'memory', 'learning.store', {
|
|
1314
|
+
insight: `[MIGRATED] ${title}: ${fullText}`,
|
|
1315
|
+
source: 'manual',
|
|
1316
|
+
confidence: 0.8,
|
|
1317
|
+
actionable: false,
|
|
1318
|
+
}, { command: 'memory', operation: 'memory.learning.store' });
|
|
1319
|
+
}
|
|
1320
|
+
else {
|
|
1321
|
+
// project | reference | user | default → observation
|
|
1322
|
+
const observeType = entryType === 'project'
|
|
1323
|
+
? 'feature'
|
|
1324
|
+
: entryType === 'reference'
|
|
1325
|
+
? 'discovery'
|
|
1326
|
+
: entryType === 'user'
|
|
1327
|
+
? 'change'
|
|
1328
|
+
: 'discovery';
|
|
1329
|
+
await dispatchFromCli('mutate', 'memory', 'observe', {
|
|
1330
|
+
text: `[MIGRATED] ${title}: ${fullText}`,
|
|
1331
|
+
title: `[MIGRATED] ${title}`,
|
|
1332
|
+
type: observeType,
|
|
1333
|
+
sourceType: 'manual',
|
|
1334
|
+
}, { command: 'memory', operation: 'memory.observe' });
|
|
1335
|
+
}
|
|
1336
|
+
importedHashes.add(hash);
|
|
1337
|
+
}
|
|
1338
|
+
stats.imported++;
|
|
1339
|
+
importedEntries.push({ file: fileName, type: entryType, title });
|
|
1340
|
+
}
|
|
1341
|
+
catch (err) {
|
|
1342
|
+
stats.errors++;
|
|
1343
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1344
|
+
errorEntries.push({ file: fileName, error: message });
|
|
1345
|
+
if (!isJson)
|
|
1346
|
+
console.error(` [ERROR] ${fileName}: ${message}`);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
if (!isDryRun) {
|
|
1350
|
+
saveImportHashes(stateFile, importedHashes);
|
|
1351
|
+
}
|
|
1352
|
+
if (isJson) {
|
|
1353
|
+
console.log(JSON.stringify({
|
|
1354
|
+
success: stats.errors === 0,
|
|
1355
|
+
data: {
|
|
1356
|
+
...stats,
|
|
1357
|
+
dryRun: isDryRun,
|
|
1358
|
+
imported: importedEntries,
|
|
1359
|
+
skipped: skippedEntries,
|
|
1360
|
+
errors: errorEntries,
|
|
1361
|
+
},
|
|
1362
|
+
meta: {
|
|
1363
|
+
operation: 'memory.import',
|
|
1364
|
+
timestamp: new Date().toISOString(),
|
|
1365
|
+
},
|
|
1366
|
+
}, null, 2));
|
|
1367
|
+
}
|
|
1368
|
+
else {
|
|
1369
|
+
console.log('');
|
|
1370
|
+
console.log('=== Import Complete ===');
|
|
1371
|
+
console.log(`Total: ${stats.total}`);
|
|
1372
|
+
console.log(`Imported: ${stats.imported}`);
|
|
1373
|
+
console.log(`Skipped: ${stats.skipped}`);
|
|
1374
|
+
console.log(`Errors: ${stats.errors}`);
|
|
1375
|
+
}
|
|
1376
|
+
if (stats.errors > 0)
|
|
1377
|
+
process.exit(1);
|
|
1378
|
+
},
|
|
1379
|
+
});
|
|
1380
|
+
/**
|
|
1381
|
+
* cleo memory doctor — read-only brain noise detector (T1262 E1-parallel).
|
|
1382
|
+
*
|
|
1383
|
+
* Scans `.cleo/brain.db` for known noise patterns without modifying any data.
|
|
1384
|
+
* Pass `--assert-clean` to exit non-zero when noise is detected (M7 gate).
|
|
1385
|
+
*/
|
|
1386
|
+
const doctorCommand = defineCommand({
|
|
1387
|
+
meta: {
|
|
1388
|
+
name: 'doctor',
|
|
1389
|
+
description: 'Read-only brain noise scan: detects duplicate-content, missing-type, missing-provenance, ' +
|
|
1390
|
+
'orphan-edge, low-confidence, and stale-unverified patterns. ' +
|
|
1391
|
+
'Use --assert-clean as the M7 entry gate before enabling Sentient v1 (`cleo sentient propose enable`).',
|
|
1392
|
+
},
|
|
1393
|
+
args: {
|
|
1394
|
+
'assert-clean': {
|
|
1395
|
+
type: 'boolean',
|
|
1396
|
+
description: 'Exit non-zero when any noise patterns are detected (M7 gate for Sentient v1)',
|
|
1397
|
+
},
|
|
1398
|
+
json: {
|
|
1399
|
+
type: 'boolean',
|
|
1400
|
+
description: 'Output as JSON',
|
|
1401
|
+
},
|
|
1402
|
+
},
|
|
1403
|
+
async run({ args }) {
|
|
1404
|
+
await dispatchFromCli('query', 'memory', 'doctor', { 'assert-clean': args['assert-clean'] }, { command: 'memory-doctor', operation: 'memory.doctor' });
|
|
1405
|
+
},
|
|
1406
|
+
});
|
|
1407
|
+
/**
|
|
1408
|
+
* cleo memory llm-status — report LLM backend resolution status (T791).
|
|
1409
|
+
*
|
|
1410
|
+
* Shows which source resolved the Anthropic API key and extraction readiness.
|
|
1411
|
+
*/
|
|
1412
|
+
const llmStatusCommand = defineCommand({
|
|
1413
|
+
meta: {
|
|
1414
|
+
name: 'llm-status',
|
|
1415
|
+
description: 'Report LLM backend resolution status and extraction readiness. ' +
|
|
1416
|
+
'Shows which source resolved the Anthropic API key (env/config/oauth/none), ' +
|
|
1417
|
+
'whether LLM extraction is enabled, and when extraction last ran.',
|
|
1418
|
+
},
|
|
1419
|
+
args: {
|
|
1420
|
+
json: {
|
|
1421
|
+
type: 'boolean',
|
|
1422
|
+
description: 'Output as JSON',
|
|
1423
|
+
},
|
|
1424
|
+
},
|
|
1425
|
+
async run() {
|
|
1426
|
+
await dispatchFromCli('query', 'memory', 'llm-status', {}, { command: 'memory-llm-status', operation: 'memory.llm-status' });
|
|
1427
|
+
},
|
|
1428
|
+
});
|
|
1429
|
+
/** cleo memory verify — promote a brain memory entry to verified=true (T792) */
|
|
1430
|
+
const verifyCommand = defineCommand({
|
|
1431
|
+
meta: {
|
|
1432
|
+
name: 'verify',
|
|
1433
|
+
description: 'Promote a brain memory entry to verified=true. ' +
|
|
1434
|
+
'Requires caller identity of cleo-prime or owner. ' +
|
|
1435
|
+
'Flips the verified flag in brain_observations (or typed table), ' +
|
|
1436
|
+
'enabling long-tier promotion and ground-truth retrieval weighting.',
|
|
1437
|
+
},
|
|
1438
|
+
args: {
|
|
1439
|
+
id: {
|
|
1440
|
+
type: 'positional',
|
|
1441
|
+
description: 'Brain entry ID to verify',
|
|
1442
|
+
required: true,
|
|
1443
|
+
},
|
|
1444
|
+
agent: {
|
|
1445
|
+
type: 'string',
|
|
1446
|
+
description: "Caller identity ('cleo-prime' or 'owner'). " +
|
|
1447
|
+
'Omit when calling from the owner terminal (no identity required).',
|
|
1448
|
+
},
|
|
1449
|
+
json: {
|
|
1450
|
+
type: 'boolean',
|
|
1451
|
+
description: 'Output as JSON',
|
|
1452
|
+
},
|
|
1453
|
+
},
|
|
1454
|
+
async run({ args }) {
|
|
1455
|
+
await dispatchFromCli('mutate', 'memory', 'verify', {
|
|
1456
|
+
id: args.id,
|
|
1457
|
+
...(args.agent !== undefined && { agent: args.agent }),
|
|
1458
|
+
}, { command: 'memory-verify', operation: 'memory.verify' });
|
|
1459
|
+
},
|
|
1460
|
+
});
|
|
1461
|
+
/** cleo memory pending-verify — list unverified but highly cited entries (T792) */
|
|
1462
|
+
const pendingVerifyCommand = defineCommand({
|
|
1463
|
+
meta: {
|
|
1464
|
+
name: 'pending-verify',
|
|
1465
|
+
description: 'List brain memory entries that are unverified (verified=false) but highly cited ' +
|
|
1466
|
+
'(citation_count >= threshold). These are strong candidates for manual verification ' +
|
|
1467
|
+
"via 'cleo memory verify <id>'.",
|
|
1468
|
+
},
|
|
1469
|
+
args: {
|
|
1470
|
+
'min-citations': {
|
|
1471
|
+
type: 'string',
|
|
1472
|
+
description: 'Minimum citation count threshold (default: 5)',
|
|
1473
|
+
},
|
|
1474
|
+
limit: {
|
|
1475
|
+
type: 'string',
|
|
1476
|
+
description: 'Maximum entries to return (default: 50)',
|
|
1477
|
+
},
|
|
1478
|
+
json: {
|
|
1479
|
+
type: 'boolean',
|
|
1480
|
+
description: 'Output as JSON',
|
|
1481
|
+
},
|
|
1482
|
+
},
|
|
1483
|
+
async run({ args }) {
|
|
1484
|
+
await dispatchFromCli('query', 'memory', 'pending-verify', {
|
|
1485
|
+
...(args['min-citations'] !== undefined && {
|
|
1486
|
+
minCitations: parseInt(args['min-citations'], 10),
|
|
1487
|
+
}),
|
|
1488
|
+
...(args.limit !== undefined && { limit: parseInt(args.limit, 10) }),
|
|
1489
|
+
}, { command: 'memory-pending-verify', operation: 'memory.pending-verify' });
|
|
1490
|
+
},
|
|
1491
|
+
});
|
|
1492
|
+
// ---------------------------------------------------------------------------
|
|
1493
|
+
// T744 — cleo memory tier <stats|promote|demote>
|
|
1494
|
+
// Provides tier observability and manual override for the 3-tier memory model.
|
|
1495
|
+
// ---------------------------------------------------------------------------
|
|
1496
|
+
/** cleo memory tier stats — tier distribution + countdown to next long-tier promotions */
|
|
1497
|
+
const tierStatsCommand = defineCommand({
|
|
1498
|
+
meta: {
|
|
1499
|
+
name: 'stats',
|
|
1500
|
+
description: 'Show tier distribution across all brain tables + countdown to next long-tier promotions (top-10)',
|
|
1501
|
+
},
|
|
1502
|
+
args: {
|
|
1503
|
+
json: {
|
|
1504
|
+
type: 'boolean',
|
|
1505
|
+
description: 'Output as JSON',
|
|
1506
|
+
},
|
|
1507
|
+
},
|
|
1508
|
+
async run({ args }) {
|
|
1509
|
+
const root = getProjectRoot();
|
|
1510
|
+
const isJson = !!args.json;
|
|
1511
|
+
try {
|
|
1512
|
+
await getBrainDb(root);
|
|
1513
|
+
const nativeDb = getBrainNativeDb();
|
|
1514
|
+
if (!nativeDb) {
|
|
1515
|
+
const msg = 'brain.db not available';
|
|
1516
|
+
if (isJson) {
|
|
1517
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1518
|
+
}
|
|
1519
|
+
else {
|
|
1520
|
+
console.error(msg);
|
|
1521
|
+
}
|
|
1522
|
+
process.exit(1);
|
|
1523
|
+
}
|
|
1524
|
+
// Per-table tier distributions
|
|
1525
|
+
const tables = ['brain_observations', 'brain_learnings', 'brain_patterns', 'brain_decisions'];
|
|
1526
|
+
const distribution = {};
|
|
1527
|
+
for (const tbl of tables) {
|
|
1528
|
+
try {
|
|
1529
|
+
const rows = nativeDb
|
|
1530
|
+
.prepare(`SELECT COALESCE(memory_tier, 'short') as tier, COUNT(*) as cnt
|
|
1531
|
+
FROM ${tbl}
|
|
1532
|
+
WHERE invalid_at IS NULL
|
|
1533
|
+
GROUP BY memory_tier`)
|
|
1534
|
+
.all();
|
|
1535
|
+
distribution[tbl] = { short: 0, medium: 0, long: 0 };
|
|
1536
|
+
for (const r of rows) {
|
|
1537
|
+
distribution[tbl][r.tier] = r.cnt;
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
catch {
|
|
1541
|
+
distribution[tbl] = { short: 0, medium: 0, long: 0 };
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
// Countdown: top-10 medium entries closest to 7-day long-tier gate
|
|
1545
|
+
// (citation_count >= 5 OR verified=1) AND created_at > (now - 7d) — approaching gate
|
|
1546
|
+
const age7dMs = 7 * 24 * 60 * 60 * 1000;
|
|
1547
|
+
const now = Date.now();
|
|
1548
|
+
const countdown = [];
|
|
1549
|
+
for (const tbl of tables) {
|
|
1550
|
+
const dateCol = tbl === 'brain_patterns' ? 'extracted_at' : 'created_at';
|
|
1551
|
+
try {
|
|
1552
|
+
const rawRows = nativeDb
|
|
1553
|
+
.prepare(`SELECT id, ${dateCol} as created_at, citation_count, verified, quality_score
|
|
1554
|
+
FROM ${tbl}
|
|
1555
|
+
WHERE memory_tier = 'medium'
|
|
1556
|
+
AND invalid_at IS NULL
|
|
1557
|
+
AND (citation_count >= 5 OR verified = 1)
|
|
1558
|
+
ORDER BY ${dateCol} ASC
|
|
1559
|
+
LIMIT 20`)
|
|
1560
|
+
.all();
|
|
1561
|
+
const rows = rawRows.map((raw) => {
|
|
1562
|
+
const r = raw;
|
|
1563
|
+
return {
|
|
1564
|
+
id: String(r['id'] ?? ''),
|
|
1565
|
+
tbl,
|
|
1566
|
+
created_at: String(r['created_at'] ?? ''),
|
|
1567
|
+
citation_count: Number(r['citation_count'] ?? 0),
|
|
1568
|
+
verified: Number(r['verified'] ?? 0),
|
|
1569
|
+
quality_score: r['quality_score'] == null ? null : Number(r['quality_score']),
|
|
1570
|
+
};
|
|
1571
|
+
});
|
|
1572
|
+
for (const r of rows) {
|
|
1573
|
+
const entryMs = new Date(r.created_at.replace(' ', 'T')).getTime();
|
|
1574
|
+
const promotionMs = entryMs + age7dMs;
|
|
1575
|
+
const daysUntil = Math.max(0, (promotionMs - now) / (24 * 60 * 60 * 1000));
|
|
1576
|
+
const track = r.citation_count >= 5 ? `citation (${r.citation_count})` : 'verified';
|
|
1577
|
+
countdown.push({ id: r.id, table: tbl, daysUntil, track });
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
catch {
|
|
1581
|
+
// Table may not have memory_tier column
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
countdown.sort((a, b) => a.daysUntil - b.daysUntil);
|
|
1585
|
+
const top10 = countdown.slice(0, 10);
|
|
1586
|
+
if (isJson) {
|
|
1587
|
+
console.log(JSON.stringify({
|
|
1588
|
+
success: true,
|
|
1589
|
+
data: { distribution, upcomingLongPromotions: top10 },
|
|
1590
|
+
meta: {
|
|
1591
|
+
operation: 'memory.tier.stats',
|
|
1592
|
+
timestamp: new Date().toISOString(),
|
|
1593
|
+
},
|
|
1594
|
+
}, null, 2));
|
|
1595
|
+
return;
|
|
1596
|
+
}
|
|
1597
|
+
// Human-readable output
|
|
1598
|
+
console.log('\nMemory Tier Distribution');
|
|
1599
|
+
console.log('========================');
|
|
1600
|
+
for (const [tbl, counts] of Object.entries(distribution)) {
|
|
1601
|
+
const shortName = tbl.replace('brain_', '');
|
|
1602
|
+
console.log(` ${shortName.padEnd(14)} short=${counts['short']} medium=${counts['medium']} long=${counts['long']}`);
|
|
1603
|
+
}
|
|
1604
|
+
if (top10.length > 0) {
|
|
1605
|
+
console.log('\nTop-10 Upcoming Long-Tier Promotions (medium → long):');
|
|
1606
|
+
console.log('-----------------------------------------------------');
|
|
1607
|
+
for (const entry of top10) {
|
|
1608
|
+
const days = entry.daysUntil.toFixed(1);
|
|
1609
|
+
const table = entry.table.replace('brain_', '');
|
|
1610
|
+
console.log(` [${table}] ${entry.id} in ${days}d via ${entry.track}`);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
else {
|
|
1614
|
+
console.log('\nNo entries currently qualifying for long-tier promotion.');
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
catch (err) {
|
|
1618
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1619
|
+
if (isJson) {
|
|
1620
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
1621
|
+
}
|
|
1622
|
+
else {
|
|
1623
|
+
console.error(`Tier stats failed: ${message}`);
|
|
1624
|
+
}
|
|
1625
|
+
process.exit(1);
|
|
1626
|
+
}
|
|
1627
|
+
},
|
|
1628
|
+
});
|
|
1629
|
+
/** cleo memory tier promote — manually promote a memory entry to a higher tier */
|
|
1630
|
+
const tierPromoteCommand = defineCommand({
|
|
1631
|
+
meta: {
|
|
1632
|
+
name: 'promote',
|
|
1633
|
+
description: 'Manually promote a memory entry to a higher tier (bypasses age gate)',
|
|
1634
|
+
},
|
|
1635
|
+
args: {
|
|
1636
|
+
id: {
|
|
1637
|
+
type: 'positional',
|
|
1638
|
+
description: 'Brain entry ID',
|
|
1639
|
+
required: true,
|
|
1640
|
+
},
|
|
1641
|
+
to: {
|
|
1642
|
+
type: 'string',
|
|
1643
|
+
description: 'Target tier: medium or long',
|
|
1644
|
+
required: true,
|
|
1645
|
+
},
|
|
1646
|
+
reason: {
|
|
1647
|
+
type: 'string',
|
|
1648
|
+
description: 'Reason for manual promotion (required)',
|
|
1649
|
+
required: true,
|
|
1650
|
+
},
|
|
1651
|
+
json: {
|
|
1652
|
+
type: 'boolean',
|
|
1653
|
+
description: 'Output as JSON',
|
|
1654
|
+
},
|
|
1655
|
+
},
|
|
1656
|
+
async run({ args }) {
|
|
1657
|
+
const root = getProjectRoot();
|
|
1658
|
+
const isJson = !!args.json;
|
|
1659
|
+
const targetTier = args.to;
|
|
1660
|
+
const reason = args.reason;
|
|
1661
|
+
const validTiers = ['medium', 'long'];
|
|
1662
|
+
if (!validTiers.includes(targetTier)) {
|
|
1663
|
+
const msg = `Invalid target tier: ${targetTier}. Must be one of: ${validTiers.join(', ')}`;
|
|
1664
|
+
if (isJson) {
|
|
1665
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1666
|
+
}
|
|
1667
|
+
else {
|
|
1668
|
+
console.error(msg);
|
|
1669
|
+
}
|
|
1670
|
+
process.exit(1);
|
|
1671
|
+
}
|
|
1672
|
+
try {
|
|
1673
|
+
await getBrainDb(root);
|
|
1674
|
+
const nativeDb = getBrainNativeDb();
|
|
1675
|
+
if (!nativeDb) {
|
|
1676
|
+
const msg = 'brain.db not available';
|
|
1677
|
+
if (isJson) {
|
|
1678
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1679
|
+
}
|
|
1680
|
+
else {
|
|
1681
|
+
console.error(msg);
|
|
1682
|
+
}
|
|
1683
|
+
process.exit(1);
|
|
1684
|
+
}
|
|
1685
|
+
const tables = ['brain_observations', 'brain_learnings', 'brain_patterns', 'brain_decisions'];
|
|
1686
|
+
const now = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
1687
|
+
let found = false;
|
|
1688
|
+
let fromTier = '';
|
|
1689
|
+
let foundTable = '';
|
|
1690
|
+
for (const tbl of tables) {
|
|
1691
|
+
try {
|
|
1692
|
+
const row = nativeDb
|
|
1693
|
+
.prepare(`SELECT id, memory_tier FROM ${tbl} WHERE id = ? AND invalid_at IS NULL LIMIT 1`)
|
|
1694
|
+
.get(args.id);
|
|
1695
|
+
if (row) {
|
|
1696
|
+
found = true;
|
|
1697
|
+
fromTier = row.memory_tier ?? 'short';
|
|
1698
|
+
foundTable = tbl;
|
|
1699
|
+
if (fromTier === targetTier) {
|
|
1700
|
+
const msg = `Entry ${args.id} is already at tier '${targetTier}'`;
|
|
1701
|
+
if (isJson) {
|
|
1702
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1703
|
+
}
|
|
1704
|
+
else {
|
|
1705
|
+
console.error(msg);
|
|
1706
|
+
}
|
|
1707
|
+
process.exit(1);
|
|
1708
|
+
}
|
|
1709
|
+
const tierOrder = { short: 0, medium: 1, long: 2 };
|
|
1710
|
+
const fromOrd = tierOrder[fromTier] ?? 0;
|
|
1711
|
+
const toOrd = tierOrder[targetTier] ?? 0;
|
|
1712
|
+
if (toOrd <= fromOrd) {
|
|
1713
|
+
const msg = `Cannot promote: '${targetTier}' is not higher than current tier '${fromTier}'. Use 'demote' to lower tiers.`;
|
|
1714
|
+
if (isJson) {
|
|
1715
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1716
|
+
}
|
|
1717
|
+
else {
|
|
1718
|
+
console.error(msg);
|
|
1719
|
+
}
|
|
1720
|
+
process.exit(1);
|
|
1721
|
+
}
|
|
1722
|
+
nativeDb
|
|
1723
|
+
.prepare(`UPDATE ${tbl} SET memory_tier = ?, updated_at = ? WHERE id = ?`)
|
|
1724
|
+
.run(targetTier, now, args.id);
|
|
1725
|
+
break;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
catch {
|
|
1729
|
+
// Try next table
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
if (!found) {
|
|
1733
|
+
const msg = `Entry '${args.id}' not found in any brain table (or is invalidated)`;
|
|
1734
|
+
if (isJson) {
|
|
1735
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1736
|
+
}
|
|
1737
|
+
else {
|
|
1738
|
+
console.error(msg);
|
|
1739
|
+
}
|
|
1740
|
+
process.exit(1);
|
|
1741
|
+
}
|
|
1742
|
+
if (isJson) {
|
|
1743
|
+
console.log(JSON.stringify({
|
|
1744
|
+
success: true,
|
|
1745
|
+
data: {
|
|
1746
|
+
id: args.id,
|
|
1747
|
+
table: foundTable,
|
|
1748
|
+
fromTier,
|
|
1749
|
+
toTier: targetTier,
|
|
1750
|
+
reason,
|
|
1751
|
+
promotedAt: now,
|
|
1752
|
+
},
|
|
1753
|
+
meta: {
|
|
1754
|
+
operation: 'memory.tier.promote',
|
|
1755
|
+
timestamp: new Date().toISOString(),
|
|
1756
|
+
},
|
|
1757
|
+
}, null, 2));
|
|
1758
|
+
}
|
|
1759
|
+
else {
|
|
1760
|
+
const shortTable = foundTable.replace('brain_', '');
|
|
1761
|
+
console.log(`Promoted [${shortTable}] ${args.id}: ${fromTier} → ${targetTier} (reason: ${reason})`);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
catch (err) {
|
|
1765
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1766
|
+
if (isJson) {
|
|
1767
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
1768
|
+
}
|
|
1769
|
+
else {
|
|
1770
|
+
console.error(`Tier promote failed: ${message}`);
|
|
1771
|
+
}
|
|
1772
|
+
process.exit(1);
|
|
1773
|
+
}
|
|
1774
|
+
},
|
|
1775
|
+
});
|
|
1776
|
+
/** cleo memory tier demote — manually demote a memory entry to a lower tier */
|
|
1777
|
+
const tierDemoteCommand = defineCommand({
|
|
1778
|
+
meta: {
|
|
1779
|
+
name: 'demote',
|
|
1780
|
+
description: 'Manually demote a memory entry to a lower tier',
|
|
1781
|
+
},
|
|
1782
|
+
args: {
|
|
1783
|
+
id: {
|
|
1784
|
+
type: 'positional',
|
|
1785
|
+
description: 'Brain entry ID',
|
|
1786
|
+
required: true,
|
|
1787
|
+
},
|
|
1788
|
+
to: {
|
|
1789
|
+
type: 'string',
|
|
1790
|
+
description: 'Target tier: short or medium',
|
|
1791
|
+
required: true,
|
|
1792
|
+
},
|
|
1793
|
+
reason: {
|
|
1794
|
+
type: 'string',
|
|
1795
|
+
description: 'Reason for manual demotion (required)',
|
|
1796
|
+
required: true,
|
|
1797
|
+
},
|
|
1798
|
+
force: {
|
|
1799
|
+
type: 'boolean',
|
|
1800
|
+
description: 'Required when demoting from long tier',
|
|
1801
|
+
},
|
|
1802
|
+
json: {
|
|
1803
|
+
type: 'boolean',
|
|
1804
|
+
description: 'Output as JSON',
|
|
1805
|
+
},
|
|
1806
|
+
},
|
|
1807
|
+
async run({ args }) {
|
|
1808
|
+
const root = getProjectRoot();
|
|
1809
|
+
const isJson = !!args.json;
|
|
1810
|
+
const targetTier = args.to;
|
|
1811
|
+
const reason = args.reason;
|
|
1812
|
+
const validTiers = ['short', 'medium'];
|
|
1813
|
+
if (!validTiers.includes(targetTier)) {
|
|
1814
|
+
const msg = `Invalid target tier for demotion: ${targetTier}. Must be one of: ${validTiers.join(', ')}`;
|
|
1815
|
+
if (isJson) {
|
|
1816
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1817
|
+
}
|
|
1818
|
+
else {
|
|
1819
|
+
console.error(msg);
|
|
1820
|
+
}
|
|
1821
|
+
process.exit(1);
|
|
1822
|
+
}
|
|
1823
|
+
try {
|
|
1824
|
+
await getBrainDb(root);
|
|
1825
|
+
const nativeDb = getBrainNativeDb();
|
|
1826
|
+
if (!nativeDb) {
|
|
1827
|
+
const msg = 'brain.db not available';
|
|
1828
|
+
if (isJson) {
|
|
1829
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1830
|
+
}
|
|
1831
|
+
else {
|
|
1832
|
+
console.error(msg);
|
|
1833
|
+
}
|
|
1834
|
+
process.exit(1);
|
|
1835
|
+
}
|
|
1836
|
+
const tables = ['brain_observations', 'brain_learnings', 'brain_patterns', 'brain_decisions'];
|
|
1837
|
+
const now = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
1838
|
+
let found = false;
|
|
1839
|
+
let fromTier = '';
|
|
1840
|
+
let foundTable = '';
|
|
1841
|
+
for (const tbl of tables) {
|
|
1842
|
+
try {
|
|
1843
|
+
const row = nativeDb
|
|
1844
|
+
.prepare(`SELECT id, memory_tier FROM ${tbl} WHERE id = ? AND invalid_at IS NULL LIMIT 1`)
|
|
1845
|
+
.get(args.id);
|
|
1846
|
+
if (row) {
|
|
1847
|
+
found = true;
|
|
1848
|
+
fromTier = row.memory_tier ?? 'short';
|
|
1849
|
+
foundTable = tbl;
|
|
1850
|
+
if (fromTier === 'long' && !args.force) {
|
|
1851
|
+
const msg = `Entry ${args.id} is in long tier. Long-tier entries are permanent. Use --force to override.`;
|
|
1852
|
+
if (isJson) {
|
|
1853
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1854
|
+
}
|
|
1855
|
+
else {
|
|
1856
|
+
console.error(msg);
|
|
1857
|
+
}
|
|
1858
|
+
process.exit(1);
|
|
1859
|
+
}
|
|
1860
|
+
if (fromTier === targetTier) {
|
|
1861
|
+
const msg = `Entry ${args.id} is already at tier '${targetTier}'`;
|
|
1862
|
+
if (isJson) {
|
|
1863
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1864
|
+
}
|
|
1865
|
+
else {
|
|
1866
|
+
console.error(msg);
|
|
1867
|
+
}
|
|
1868
|
+
process.exit(1);
|
|
1869
|
+
}
|
|
1870
|
+
const tierOrder = { short: 0, medium: 1, long: 2 };
|
|
1871
|
+
const fromOrd = tierOrder[fromTier] ?? 0;
|
|
1872
|
+
const toOrd = tierOrder[targetTier] ?? 0;
|
|
1873
|
+
if (toOrd >= fromOrd) {
|
|
1874
|
+
const msg = `Cannot demote: '${targetTier}' is not lower than current tier '${fromTier}'. Use 'promote' to raise tiers.`;
|
|
1875
|
+
if (isJson) {
|
|
1876
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1877
|
+
}
|
|
1878
|
+
else {
|
|
1879
|
+
console.error(msg);
|
|
1880
|
+
}
|
|
1881
|
+
process.exit(1);
|
|
1882
|
+
}
|
|
1883
|
+
nativeDb
|
|
1884
|
+
.prepare(`UPDATE ${tbl} SET memory_tier = ?, updated_at = ? WHERE id = ?`)
|
|
1885
|
+
.run(targetTier, now, args.id);
|
|
1886
|
+
break;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
catch {
|
|
1890
|
+
// Try next table
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
if (!found) {
|
|
1894
|
+
const msg = `Entry '${args.id}' not found in any brain table (or is invalidated)`;
|
|
1895
|
+
if (isJson) {
|
|
1896
|
+
console.log(JSON.stringify({ success: false, error: msg }));
|
|
1897
|
+
}
|
|
1898
|
+
else {
|
|
1899
|
+
console.error(msg);
|
|
1900
|
+
}
|
|
1901
|
+
process.exit(1);
|
|
1902
|
+
}
|
|
1903
|
+
if (isJson) {
|
|
1904
|
+
console.log(JSON.stringify({
|
|
1905
|
+
success: true,
|
|
1906
|
+
data: {
|
|
1907
|
+
id: args.id,
|
|
1908
|
+
table: foundTable,
|
|
1909
|
+
fromTier,
|
|
1910
|
+
toTier: targetTier,
|
|
1911
|
+
reason,
|
|
1912
|
+
demotedAt: now,
|
|
1913
|
+
},
|
|
1914
|
+
meta: {
|
|
1915
|
+
operation: 'memory.tier.demote',
|
|
1916
|
+
timestamp: new Date().toISOString(),
|
|
1917
|
+
},
|
|
1918
|
+
}, null, 2));
|
|
1919
|
+
}
|
|
1920
|
+
else {
|
|
1921
|
+
const shortTable = foundTable.replace('brain_', '');
|
|
1922
|
+
console.log(`Demoted [${shortTable}] ${args.id}: ${fromTier} → ${targetTier} (reason: ${reason})`);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
catch (err) {
|
|
1926
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1927
|
+
if (isJson) {
|
|
1928
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
1929
|
+
}
|
|
1930
|
+
else {
|
|
1931
|
+
console.error(`Tier demote failed: ${message}`);
|
|
1932
|
+
}
|
|
1933
|
+
process.exit(1);
|
|
1934
|
+
}
|
|
1935
|
+
},
|
|
1936
|
+
});
|
|
1937
|
+
// ---------------------------------------------------------------------------
|
|
1938
|
+
// T1013 — new memory subcommands (T1003 backfill, T1004 precompact-flush,
|
|
1939
|
+
// T1006 digest / recent / diary / watch)
|
|
1940
|
+
// ---------------------------------------------------------------------------
|
|
1941
|
+
/**
|
|
1942
|
+
* Factory helper that wraps a `dispatchFromCli` call in a minimal citty
|
|
1943
|
+
* subcommand shell. Extracted to eliminate copy-paste across the new
|
|
1944
|
+
* memory subcommands (T1003/T1004/T1006) per AGENTS.md DRY rules.
|
|
1945
|
+
*
|
|
1946
|
+
* The returned `CommandDef` always accepts a shared `--json` flag; all
|
|
1947
|
+
* other args must be supplied by the caller. The `paramBuilder` maps the
|
|
1948
|
+
* parsed citty args into the dispatch payload.
|
|
1949
|
+
*
|
|
1950
|
+
* @param opts - Subcommand metadata + dispatch wiring.
|
|
1951
|
+
* @returns A citty `CommandDef` ready to drop into `subCommands: { ... }`.
|
|
1952
|
+
*
|
|
1953
|
+
* @internal
|
|
1954
|
+
*/
|
|
1955
|
+
function makeMemorySubcommand(opts) {
|
|
1956
|
+
// Merge in a shared --json flag so every subcommand supports JSON output
|
|
1957
|
+
// without duplicating the boilerplate arg at every definition site.
|
|
1958
|
+
const mergedArgs = {
|
|
1959
|
+
...opts.args,
|
|
1960
|
+
json: {
|
|
1961
|
+
type: 'boolean',
|
|
1962
|
+
description: 'Output as JSON',
|
|
1963
|
+
},
|
|
1964
|
+
};
|
|
1965
|
+
return defineCommand({
|
|
1966
|
+
meta: { name: opts.name, description: opts.description },
|
|
1967
|
+
args: mergedArgs,
|
|
1968
|
+
async run({ args }) {
|
|
1969
|
+
const params = opts.paramBuilder(args);
|
|
1970
|
+
await dispatchFromCli(opts.gateway, 'memory', opts.operation, params, opts.output);
|
|
1971
|
+
},
|
|
1972
|
+
});
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* cleo memory precompact-flush — T1004.
|
|
1976
|
+
*
|
|
1977
|
+
* Thin wrapper around `precompactFlush()` that unblocks the bash-shim
|
|
1978
|
+
* `precompact-safestop.sh` hook path. This is the CRITICAL runtime bug
|
|
1979
|
+
* fix called out in T1013: without this command, the shim's
|
|
1980
|
+
* `cleo memory precompact-flush` invocation resolves to E_NO_HANDLER.
|
|
1981
|
+
*/
|
|
1982
|
+
const precompactFlushCommand = makeMemorySubcommand({
|
|
1983
|
+
name: 'precompact-flush',
|
|
1984
|
+
description: 'Flush in-flight observations to brain.db and checkpoint the SQLite WAL before context compaction (T1004).',
|
|
1985
|
+
args: {},
|
|
1986
|
+
gateway: 'mutate',
|
|
1987
|
+
operation: 'precompact-flush',
|
|
1988
|
+
output: { command: 'memory-precompact-flush', operation: 'memory.precompact-flush' },
|
|
1989
|
+
paramBuilder: () => ({}),
|
|
1990
|
+
});
|
|
1991
|
+
/**
|
|
1992
|
+
* cleo memory backfill run — T1003.
|
|
1993
|
+
*
|
|
1994
|
+
* Stage a new brain-graph backfill run. Rows are written to a staging
|
|
1995
|
+
* manifest pending approval via `cleo memory backfill approve <runId>`.
|
|
1996
|
+
*/
|
|
1997
|
+
const backfillRunCommand = makeMemorySubcommand({
|
|
1998
|
+
name: 'run',
|
|
1999
|
+
description: 'Stage a brain-graph backfill run (pending approval). Pass --source to tag the run with a human-readable descriptor.',
|
|
2000
|
+
args: {
|
|
2001
|
+
source: {
|
|
2002
|
+
type: 'string',
|
|
2003
|
+
description: 'Human-readable descriptor for the backfill source (file path, session ID, etc).',
|
|
2004
|
+
},
|
|
2005
|
+
kind: {
|
|
2006
|
+
type: 'string',
|
|
2007
|
+
description: "Backfill kind (default: 'graph-backfill').",
|
|
2008
|
+
},
|
|
2009
|
+
'target-table': {
|
|
2010
|
+
type: 'string',
|
|
2011
|
+
description: "Target table (default: 'brain_page_nodes').",
|
|
2012
|
+
},
|
|
2013
|
+
},
|
|
2014
|
+
gateway: 'mutate',
|
|
2015
|
+
operation: 'backfill.run',
|
|
2016
|
+
output: { command: 'memory-backfill-run', operation: 'memory.backfill.run' },
|
|
2017
|
+
paramBuilder: (args) => ({
|
|
2018
|
+
...(args['source'] !== undefined && { source: args['source'] }),
|
|
2019
|
+
...(args['kind'] !== undefined && { kind: args['kind'] }),
|
|
2020
|
+
...(args['target-table'] !== undefined && { targetTable: args['target-table'] }),
|
|
2021
|
+
}),
|
|
2022
|
+
});
|
|
2023
|
+
/**
|
|
2024
|
+
* cleo memory backfill approve <runId> — T1003.
|
|
2025
|
+
*
|
|
2026
|
+
* Promote a staged backfill run to committed state. Idempotent: a run that
|
|
2027
|
+
* has already been approved returns `alreadySettled: true` without error.
|
|
2028
|
+
*/
|
|
2029
|
+
const backfillApproveCommand = makeMemorySubcommand({
|
|
2030
|
+
name: 'approve',
|
|
2031
|
+
description: 'Approve a staged backfill run (commits rows to brain_page_nodes). Idempotent — re-approval returns alreadySettled=true.',
|
|
2032
|
+
args: {
|
|
2033
|
+
runId: {
|
|
2034
|
+
type: 'positional',
|
|
2035
|
+
description: 'Backfill run ID to approve',
|
|
2036
|
+
required: true,
|
|
2037
|
+
},
|
|
2038
|
+
'approved-by': {
|
|
2039
|
+
type: 'string',
|
|
2040
|
+
description: "Identity of the approver (default: 'cli').",
|
|
2041
|
+
},
|
|
2042
|
+
},
|
|
2043
|
+
gateway: 'mutate',
|
|
2044
|
+
operation: 'backfill.approve',
|
|
2045
|
+
output: { command: 'memory-backfill-approve', operation: 'memory.backfill.approve' },
|
|
2046
|
+
paramBuilder: (args) => ({
|
|
2047
|
+
runId: args['runId'],
|
|
2048
|
+
...(args['approved-by'] !== undefined && { approvedBy: args['approved-by'] }),
|
|
2049
|
+
}),
|
|
2050
|
+
});
|
|
2051
|
+
/**
|
|
2052
|
+
* cleo memory backfill rollback <runId> — T1003.
|
|
2053
|
+
*
|
|
2054
|
+
* Roll back a previously-staged or committed backfill run. Staged rows are
|
|
2055
|
+
* dropped in-place; committed rows are deleted from the live graph tables.
|
|
2056
|
+
*/
|
|
2057
|
+
const backfillRollbackCommand = makeMemorySubcommand({
|
|
2058
|
+
name: 'rollback',
|
|
2059
|
+
description: 'Rollback a staged or committed backfill run. Removes any rows written to brain_page_nodes.',
|
|
2060
|
+
args: {
|
|
2061
|
+
runId: {
|
|
2062
|
+
type: 'positional',
|
|
2063
|
+
description: 'Backfill run ID to rollback',
|
|
2064
|
+
required: true,
|
|
2065
|
+
},
|
|
2066
|
+
},
|
|
2067
|
+
gateway: 'mutate',
|
|
2068
|
+
operation: 'backfill.rollback',
|
|
2069
|
+
output: { command: 'memory-backfill-rollback', operation: 'memory.backfill.rollback' },
|
|
2070
|
+
paramBuilder: (args) => ({
|
|
2071
|
+
runId: args['runId'],
|
|
2072
|
+
}),
|
|
2073
|
+
});
|
|
2074
|
+
/**
|
|
2075
|
+
* cleo memory backfill — group command hosting run / approve / rollback (T1003).
|
|
2076
|
+
*/
|
|
2077
|
+
const backfillCommand = defineCommand({
|
|
2078
|
+
meta: {
|
|
2079
|
+
name: 'backfill',
|
|
2080
|
+
description: 'Staged brain-graph backfill operations: run, approve, rollback (T1003).',
|
|
2081
|
+
},
|
|
2082
|
+
subCommands: {
|
|
2083
|
+
run: backfillRunCommand,
|
|
2084
|
+
approve: backfillApproveCommand,
|
|
2085
|
+
rollback: backfillRollbackCommand,
|
|
2086
|
+
},
|
|
2087
|
+
async run({ cmd, rawArgs }) {
|
|
2088
|
+
const firstArg = rawArgs?.find((a) => !a.startsWith('-'));
|
|
2089
|
+
if (firstArg && cmd.subCommands && firstArg in cmd.subCommands)
|
|
2090
|
+
return;
|
|
2091
|
+
await showUsage(cmd);
|
|
2092
|
+
},
|
|
2093
|
+
});
|
|
2094
|
+
/**
|
|
2095
|
+
* cleo memory digest — T1006.
|
|
2096
|
+
*
|
|
2097
|
+
* Summarized top-N observations as a session-briefing digest. Wraps the
|
|
2098
|
+
* `memory.digest` dispatch operation which sorts by citation_count +
|
|
2099
|
+
* quality_score DESC.
|
|
2100
|
+
*/
|
|
2101
|
+
const digestCommand = makeMemorySubcommand({
|
|
2102
|
+
name: 'digest',
|
|
2103
|
+
description: 'Summarized top-N brain observations for session briefing (T1006). Sorted by citation_count + quality_score.',
|
|
2104
|
+
args: {
|
|
2105
|
+
limit: {
|
|
2106
|
+
type: 'string',
|
|
2107
|
+
description: 'Maximum number of observations to include (default: 10).',
|
|
2108
|
+
},
|
|
2109
|
+
},
|
|
2110
|
+
gateway: 'query',
|
|
2111
|
+
operation: 'digest',
|
|
2112
|
+
output: { command: 'memory-digest', operation: 'memory.digest' },
|
|
2113
|
+
paramBuilder: (args) => ({
|
|
2114
|
+
...(args['limit'] !== undefined && { limit: parseInt(args['limit'], 10) }),
|
|
2115
|
+
}),
|
|
2116
|
+
});
|
|
2117
|
+
/**
|
|
2118
|
+
* cleo memory recent — T1006.
|
|
2119
|
+
*
|
|
2120
|
+
* Tail recent observations with optional type / session / tier filters.
|
|
2121
|
+
* Supports a compact `since` syntax (`24h`, `7d`, `30m`, or ISO timestamp).
|
|
2122
|
+
*/
|
|
2123
|
+
const recentCommand = makeMemorySubcommand({
|
|
2124
|
+
name: 'recent',
|
|
2125
|
+
description: 'Tail recent brain observations with optional filters (T1006). --since accepts 30m / 24h / 7d or an ISO timestamp.',
|
|
2126
|
+
args: {
|
|
2127
|
+
limit: {
|
|
2128
|
+
type: 'string',
|
|
2129
|
+
description: 'Maximum number of observations to return (default: 20).',
|
|
2130
|
+
},
|
|
2131
|
+
type: {
|
|
2132
|
+
type: 'string',
|
|
2133
|
+
description: 'Filter by observation type (discovery, decision, bugfix, refactor, feature, change, diary, session-summary).',
|
|
2134
|
+
},
|
|
2135
|
+
since: {
|
|
2136
|
+
type: 'string',
|
|
2137
|
+
description: 'Duration (e.g. 24h, 7d, 30m) or ISO timestamp lower bound.',
|
|
2138
|
+
},
|
|
2139
|
+
session: {
|
|
2140
|
+
type: 'string',
|
|
2141
|
+
description: 'Filter by source session ID.',
|
|
2142
|
+
},
|
|
2143
|
+
tier: {
|
|
2144
|
+
type: 'string',
|
|
2145
|
+
description: "Filter by memory tier ('short', 'medium', 'long').",
|
|
2146
|
+
},
|
|
2147
|
+
},
|
|
2148
|
+
gateway: 'query',
|
|
2149
|
+
operation: 'recent',
|
|
2150
|
+
output: { command: 'memory-recent', operation: 'memory.recent' },
|
|
2151
|
+
paramBuilder: (args) => ({
|
|
2152
|
+
...(args['limit'] !== undefined && { limit: parseInt(args['limit'], 10) }),
|
|
2153
|
+
...(args['type'] !== undefined && { type: args['type'] }),
|
|
2154
|
+
...(args['since'] !== undefined && { since: args['since'] }),
|
|
2155
|
+
...(args['session'] !== undefined && { session: args['session'] }),
|
|
2156
|
+
...(args['tier'] !== undefined && { tier: args['tier'] }),
|
|
2157
|
+
}),
|
|
2158
|
+
});
|
|
2159
|
+
/**
|
|
2160
|
+
* cleo memory diary read — T1006.
|
|
2161
|
+
*
|
|
2162
|
+
* Read recent diary-typed observations. Requires the `diary` enum value
|
|
2163
|
+
* shipped by T1005 (already in main).
|
|
2164
|
+
*/
|
|
2165
|
+
const diaryReadCommand = makeMemorySubcommand({
|
|
2166
|
+
name: 'read',
|
|
2167
|
+
description: 'Read recent diary-typed observations (T1006).',
|
|
2168
|
+
args: {
|
|
2169
|
+
limit: {
|
|
2170
|
+
type: 'string',
|
|
2171
|
+
description: 'Maximum number of diary entries to return (default: 20).',
|
|
2172
|
+
},
|
|
2173
|
+
},
|
|
2174
|
+
gateway: 'query',
|
|
2175
|
+
operation: 'diary',
|
|
2176
|
+
output: { command: 'memory-diary-read', operation: 'memory.diary' },
|
|
2177
|
+
paramBuilder: (args) => ({
|
|
2178
|
+
...(args['limit'] !== undefined && { limit: parseInt(args['limit'], 10) }),
|
|
2179
|
+
}),
|
|
2180
|
+
});
|
|
2181
|
+
/**
|
|
2182
|
+
* cleo memory diary write <text> — T1006.
|
|
2183
|
+
*
|
|
2184
|
+
* Write a diary-typed observation (thin wrapper around `memory.diary.write`
|
|
2185
|
+
* which delegates to `memoryObserve` with `type: 'diary'`).
|
|
2186
|
+
*/
|
|
2187
|
+
const diaryWriteCommand = makeMemorySubcommand({
|
|
2188
|
+
name: 'write',
|
|
2189
|
+
description: 'Write a diary-typed observation to brain.db (T1006).',
|
|
2190
|
+
args: {
|
|
2191
|
+
text: {
|
|
2192
|
+
type: 'positional',
|
|
2193
|
+
description: 'Diary entry text',
|
|
2194
|
+
required: true,
|
|
2195
|
+
},
|
|
2196
|
+
title: {
|
|
2197
|
+
type: 'string',
|
|
2198
|
+
description: 'Optional diary entry title (defaults to first 120 chars of text).',
|
|
2199
|
+
},
|
|
2200
|
+
agent: {
|
|
2201
|
+
type: 'string',
|
|
2202
|
+
description: 'Optional agent provenance (e.g. cleo-prime, historian).',
|
|
2203
|
+
},
|
|
2204
|
+
},
|
|
2205
|
+
gateway: 'mutate',
|
|
2206
|
+
operation: 'diary.write',
|
|
2207
|
+
output: { command: 'memory-diary-write', operation: 'memory.diary.write' },
|
|
2208
|
+
paramBuilder: (args) => ({
|
|
2209
|
+
text: args['text'],
|
|
2210
|
+
...(args['title'] !== undefined && { title: args['title'] }),
|
|
2211
|
+
...(args['agent'] !== undefined && { agent: args['agent'] }),
|
|
2212
|
+
}),
|
|
2213
|
+
});
|
|
2214
|
+
/**
|
|
2215
|
+
* cleo memory diary — group command hosting read / write subcommands (T1006).
|
|
2216
|
+
*/
|
|
2217
|
+
const diaryCommand = defineCommand({
|
|
2218
|
+
meta: {
|
|
2219
|
+
name: 'diary',
|
|
2220
|
+
description: 'Read or write diary-typed brain observations (T1006).',
|
|
2221
|
+
},
|
|
2222
|
+
subCommands: {
|
|
2223
|
+
read: diaryReadCommand,
|
|
2224
|
+
write: diaryWriteCommand,
|
|
2225
|
+
},
|
|
2226
|
+
async run({ cmd, rawArgs }) {
|
|
2227
|
+
const firstArg = rawArgs?.find((a) => !a.startsWith('-'));
|
|
2228
|
+
if (firstArg && cmd.subCommands && firstArg in cmd.subCommands)
|
|
2229
|
+
return;
|
|
2230
|
+
await showUsage(cmd);
|
|
2231
|
+
},
|
|
2232
|
+
});
|
|
2233
|
+
/**
|
|
2234
|
+
* cleo memory watch — T1006.
|
|
2235
|
+
*
|
|
2236
|
+
* Long-poll stream of recent brain writes. Without `--follow` the command
|
|
2237
|
+
* returns a single batch and exits. With `--follow`, it polls the
|
|
2238
|
+
* dispatch `memory.watch` operation using the returned cursor until
|
|
2239
|
+
* stdout closes or SIGINT. Each event is emitted as an SSE-style
|
|
2240
|
+
* `data: <json>\n\n` line so that downstream consumers can pipe into
|
|
2241
|
+
* EventSource-compatible clients.
|
|
2242
|
+
*/
|
|
2243
|
+
const watchCommand = defineCommand({
|
|
2244
|
+
meta: {
|
|
2245
|
+
name: 'watch',
|
|
2246
|
+
description: 'Long-poll stream of recent brain writes. Use --follow to stream continuously as SSE-style events.',
|
|
2247
|
+
},
|
|
2248
|
+
args: {
|
|
2249
|
+
cursor: {
|
|
2250
|
+
type: 'string',
|
|
2251
|
+
description: 'Resume cursor (created_at lower bound) from a previous watch call.',
|
|
2252
|
+
},
|
|
2253
|
+
limit: {
|
|
2254
|
+
type: 'string',
|
|
2255
|
+
description: 'Maximum events per poll (default: 10).',
|
|
2256
|
+
},
|
|
2257
|
+
follow: {
|
|
2258
|
+
type: 'boolean',
|
|
2259
|
+
description: 'Stream continuously; polls every --interval ms until interrupted.',
|
|
2260
|
+
},
|
|
2261
|
+
interval: {
|
|
2262
|
+
type: 'string',
|
|
2263
|
+
description: 'Poll interval in milliseconds when --follow is set (default: 1000).',
|
|
2264
|
+
},
|
|
2265
|
+
json: {
|
|
2266
|
+
type: 'boolean',
|
|
2267
|
+
description: 'Output as JSON (non-follow mode only).',
|
|
2268
|
+
},
|
|
2269
|
+
},
|
|
2270
|
+
async run({ args }) {
|
|
2271
|
+
const buildParams = (cursor) => ({
|
|
2272
|
+
...(cursor !== undefined && { cursor }),
|
|
2273
|
+
...(args.limit !== undefined && { limit: parseInt(args.limit, 10) }),
|
|
2274
|
+
});
|
|
2275
|
+
// Non-follow mode: single dispatch → normal LAFS output.
|
|
2276
|
+
if (!args.follow) {
|
|
2277
|
+
await dispatchFromCli('query', 'memory', 'watch', buildParams(args.cursor), { command: 'memory-watch', operation: 'memory.watch' });
|
|
2278
|
+
return;
|
|
2279
|
+
}
|
|
2280
|
+
// Follow mode: SSE-style stdout stream. Emit a `ping` event, then poll
|
|
2281
|
+
// `memory.watch` every interval, emitting each event as
|
|
2282
|
+
// `event: observation\ndata: <json>\n\n`. Graceful shutdown on SIGINT.
|
|
2283
|
+
const intervalMs = args.interval !== undefined ? parseInt(args.interval, 10) : 1000;
|
|
2284
|
+
let cursor = args.cursor;
|
|
2285
|
+
let running = true;
|
|
2286
|
+
const onSignal = () => {
|
|
2287
|
+
running = false;
|
|
2288
|
+
};
|
|
2289
|
+
process.once('SIGINT', onSignal);
|
|
2290
|
+
process.once('SIGTERM', onSignal);
|
|
2291
|
+
// Initial ping so downstream EventSource-like clients see the stream open.
|
|
2292
|
+
process.stdout.write(`event: ping\ndata: ${JSON.stringify({ ts: new Date().toISOString() })}\n\n`);
|
|
2293
|
+
while (running) {
|
|
2294
|
+
const response = await dispatchRaw('query', 'memory', 'watch', buildParams(cursor));
|
|
2295
|
+
if (!response.success) {
|
|
2296
|
+
handleRawError(response, { command: 'memory-watch', operation: 'memory.watch' });
|
|
2297
|
+
return; // handleRawError calls process.exit on failure
|
|
2298
|
+
}
|
|
2299
|
+
const data = response.data;
|
|
2300
|
+
const events = data.events ?? [];
|
|
2301
|
+
for (const event of events) {
|
|
2302
|
+
process.stdout.write(`event: observation\ndata: ${JSON.stringify(event)}\n\n`);
|
|
2303
|
+
}
|
|
2304
|
+
if (typeof data.nextCursor === 'string') {
|
|
2305
|
+
cursor = data.nextCursor;
|
|
2306
|
+
}
|
|
2307
|
+
if (!running)
|
|
2308
|
+
break;
|
|
2309
|
+
// Fixed-interval sleep between polls. Resolves early on SIGINT because
|
|
2310
|
+
// `running` is re-checked on the next loop pass.
|
|
2311
|
+
await new Promise((resolve) => {
|
|
2312
|
+
const timer = setTimeout(resolve, intervalMs);
|
|
2313
|
+
// Allow the process to exit cleanly even if the timer is outstanding.
|
|
2314
|
+
timer.unref?.();
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
// Graceful stream close marker.
|
|
2318
|
+
process.stdout.write(`event: close\ndata: ${JSON.stringify({ ts: new Date().toISOString() })}\n\n`);
|
|
2319
|
+
},
|
|
2320
|
+
});
|
|
2321
|
+
/** cleo memory tier — memory tier management (stats, promote, demote) (T744) */
|
|
2322
|
+
const tierCommand = defineCommand({
|
|
2323
|
+
meta: { name: 'tier', description: 'Memory tier management: stats, promote, demote' },
|
|
2324
|
+
subCommands: {
|
|
2325
|
+
stats: tierStatsCommand,
|
|
2326
|
+
promote: tierPromoteCommand,
|
|
2327
|
+
demote: tierDemoteCommand,
|
|
2328
|
+
},
|
|
2329
|
+
});
|
|
2330
|
+
/**
|
|
2331
|
+
* cleo memory sweep — T1147 W7 BRAIN noise sweep (shadow-write envelope).
|
|
2332
|
+
*
|
|
2333
|
+
* `--dry-run` Detect noise candidates without staging DB writes.
|
|
2334
|
+
* `--approve <runId>` Apply a staged sweep to live tables (with killSwitch gate).
|
|
2335
|
+
* `--status` List recent noise-sweep-2440 runs.
|
|
2336
|
+
* `--rollback <runId>` Discard a staged run without applying changes.
|
|
2337
|
+
*/
|
|
2338
|
+
const sweepCommand = defineCommand({
|
|
2339
|
+
meta: {
|
|
2340
|
+
name: 'sweep',
|
|
2341
|
+
description: 'T1147 W7 BRAIN noise sweep. --dry-run: detect noise candidates. ' +
|
|
2342
|
+
'--approve <runId>: apply to live tables. --status: list runs. ' +
|
|
2343
|
+
'--rollback <runId>: discard staged run.',
|
|
2344
|
+
},
|
|
2345
|
+
args: {
|
|
2346
|
+
'dry-run': {
|
|
2347
|
+
type: 'boolean',
|
|
2348
|
+
description: 'Detect noise candidates without staging DB writes.',
|
|
2349
|
+
},
|
|
2350
|
+
approve: {
|
|
2351
|
+
type: 'string',
|
|
2352
|
+
description: 'Run ID to approve and apply to live tables.',
|
|
2353
|
+
},
|
|
2354
|
+
status: {
|
|
2355
|
+
type: 'boolean',
|
|
2356
|
+
description: 'List recent noise-sweep-2440 runs.',
|
|
2357
|
+
},
|
|
2358
|
+
rollback: {
|
|
2359
|
+
type: 'string',
|
|
2360
|
+
description: 'Run ID to roll back without applying changes.',
|
|
2361
|
+
},
|
|
2362
|
+
json: {
|
|
2363
|
+
type: 'boolean',
|
|
2364
|
+
description: 'Output as JSON',
|
|
2365
|
+
},
|
|
2366
|
+
},
|
|
2367
|
+
async run({ args, }) {
|
|
2368
|
+
const gateway = args.approve || args.rollback ? 'mutate' : 'query';
|
|
2369
|
+
await dispatchFromCli(gateway, 'memory', 'sweep', {
|
|
2370
|
+
'dry-run': args['dry-run'],
|
|
2371
|
+
approve: args.approve,
|
|
2372
|
+
status: args.status,
|
|
2373
|
+
rollback: args.rollback,
|
|
2374
|
+
}, { command: 'memory-sweep', operation: 'memory.sweep' });
|
|
2375
|
+
},
|
|
2376
|
+
});
|
|
2377
|
+
// ---------------------------------------------------------------------------
|
|
2378
|
+
// Root export
|
|
2379
|
+
// ---------------------------------------------------------------------------
|
|
2380
|
+
/**
|
|
2381
|
+
* Root memory command group — registers all BRAIN memory subcommands.
|
|
2382
|
+
*
|
|
2383
|
+
* Dispatches to `memory.*` registry operations.
|
|
2384
|
+
*/
|
|
2385
|
+
export const memoryCommand = defineCommand({
|
|
2386
|
+
meta: { name: 'memory', description: 'BRAIN memory operations (patterns, learnings)' },
|
|
2387
|
+
subCommands: {
|
|
2388
|
+
store: storeCommand,
|
|
2389
|
+
find: findCommand,
|
|
2390
|
+
stats: statsCommand,
|
|
2391
|
+
observe: observeCommand,
|
|
2392
|
+
timeline: timelineCommand,
|
|
2393
|
+
fetch: fetchCommand,
|
|
2394
|
+
'decision-find': decisionFindCommand,
|
|
2395
|
+
'decision-store': decisionStoreCommand,
|
|
2396
|
+
link: linkCommand,
|
|
2397
|
+
trace: traceCommand,
|
|
2398
|
+
related: relatedCommand,
|
|
2399
|
+
context: contextCommand,
|
|
2400
|
+
'graph-stats': graphStatsCommand,
|
|
2401
|
+
'graph-show': graphShowCommand,
|
|
2402
|
+
'graph-neighbors': graphNeighborsCommand,
|
|
2403
|
+
'graph-add': graphAddCommand,
|
|
2404
|
+
'graph-remove': graphRemoveCommand,
|
|
2405
|
+
'reason-why': reasonWhyCommand,
|
|
2406
|
+
'reason-similar': reasonSimilarCommand,
|
|
2407
|
+
'search-hybrid': searchHybridCommand,
|
|
2408
|
+
'code-links': codeLinksCommand,
|
|
2409
|
+
'code-auto-link': codeAutoLinkCommand,
|
|
2410
|
+
'code-memories-for-code': codeMemoriesForCodeCommand,
|
|
2411
|
+
'code-for-memory': codeForMemoryCommand,
|
|
2412
|
+
consolidate: consolidateCommand,
|
|
2413
|
+
dream: dreamCommand,
|
|
2414
|
+
reflect: reflectCommand,
|
|
2415
|
+
'dedup-scan': dedupScanCommand,
|
|
2416
|
+
import: importCommand,
|
|
2417
|
+
doctor: doctorCommand,
|
|
2418
|
+
'llm-status': llmStatusCommand,
|
|
2419
|
+
verify: verifyCommand,
|
|
2420
|
+
'pending-verify': pendingVerifyCommand,
|
|
2421
|
+
tier: tierCommand,
|
|
2422
|
+
// T1013 — new memory subcommands
|
|
2423
|
+
'precompact-flush': precompactFlushCommand,
|
|
2424
|
+
backfill: backfillCommand,
|
|
2425
|
+
digest: digestCommand,
|
|
2426
|
+
recent: recentCommand,
|
|
2427
|
+
diary: diaryCommand,
|
|
2428
|
+
watch: watchCommand,
|
|
2429
|
+
// T1147 W7 — BRAIN noise sweep
|
|
2430
|
+
sweep: sweepCommand,
|
|
2431
|
+
},
|
|
2432
|
+
async run({ cmd, rawArgs }) {
|
|
2433
|
+
const firstArg = rawArgs?.find((a) => !a.startsWith('-'));
|
|
2434
|
+
if (firstArg && cmd.subCommands && firstArg in cmd.subCommands)
|
|
2435
|
+
return;
|
|
2436
|
+
await showUsage(cmd);
|
|
2437
|
+
},
|
|
2438
|
+
});
|
|
2439
|
+
//# sourceMappingURL=memory.js.map
|