hippo-memory 1.52.3 → 1.52.5
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/README.md +70 -17
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +85 -29
- package/dist/connectors/github/cli-impl.js +0 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +2 -2
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +2 -2
- package/package.json +21 -13
package/README.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
# 🦛 Hippo
|
|
1
|
+
# 🦛 Hippo: memory for AI agents that learns what is wrong
|
|
2
2
|
|
|
3
3
|
**Hippo learns what is wrong and stops repeating it.** Good memory is knowing what to forget: what turned out wrong, what got replaced, what nobody used.
|
|
4
4
|
|
|
5
5
|
[](https://npmjs.com/package/hippo-memory)
|
|
6
|
-
[](https://npmjs.com/package/hippo-memory)
|
|
7
|
+
[](https://github.com/kitfunso/hippo-memory/actions/workflows/ci.yml)
|
|
8
|
+
[](https://github.com/kitfunso/hippo-memory/blob/master/LICENSE)
|
|
7
9
|
[](https://hippo-memory.com)
|
|
8
10
|
|
|
9
11
|
<p align="center">
|
|
10
|
-
<img src="
|
|
12
|
+
<img src="https://raw.githubusercontent.com/kitfunso/hippo-memory/master/assets/hippo-init.svg" alt="hippo init --scan ~ initializing memory across all repos" width="720">
|
|
11
13
|
</p>
|
|
12
14
|
|
|
13
15
|
A memory layer for AI agents. Mark a memory wrong and it stops coming back. A newer fact replaces the old one. Memories you use get stronger. Provenance on every memory. SQLite under the hood, zero runtime deps, works with every CLI agent you have.
|
|
@@ -27,6 +29,8 @@ Storage: SQLite backbone with markdown mirrors. Git-trackable, human-reada
|
|
|
27
29
|
Dependencies: Zero runtime deps. Node.js 22.16+. Optional embeddings: bring-your-own local Transformers.js (`npm i @huggingface/transformers`, or legacy `@xenova/transformers`) or an opt-in API embedder (OpenAI/Voyage/Cohere). Nothing is auto-installed.
|
|
28
30
|
```
|
|
29
31
|
|
|
32
|
+
**Contents:** [Why](#why-this-exists) · [Receipts](#receipts) · [Quick start](#quick-start) · [Agent setup](#framework-integrations) · [MCP server](#mcp-server) · [How it works](#how-it-works) · [Features](#key-features) · [CLI](#cli-reference) · [Comparison](#comparison) · [Benchmarks](#benchmarks) · [FAQ](#faq) · [Contributing](#contributing)
|
|
33
|
+
|
|
30
34
|
---
|
|
31
35
|
|
|
32
36
|
## Why this exists
|
|
@@ -112,7 +116,7 @@ hippo init
|
|
|
112
116
|
# Auto-installed claude-code hook in CLAUDE.md
|
|
113
117
|
```
|
|
114
118
|
|
|
115
|
-
If you have a `CLAUDE.md`, it patches it. `AGENTS.md` for Codex/OpenClaw/OpenCode. `.cursorrules` for Cursor. Your agent starts using Hippo on its next session. For Codex session capture, Hippo wraps the codex launcher only when you explicitly opt in with `hippo hook install codex` (init prints the command when it detects Codex; undo anytime with `hippo hook uninstall codex`).
|
|
119
|
+
If you have a `CLAUDE.md`, it patches it. `AGENTS.md` for Codex/OpenClaw/OpenCode/Pi. `.cursorrules` for Cursor. Your agent starts using Hippo on its next session. For Codex session capture, Hippo wraps the codex launcher only when you explicitly opt in with `hippo hook install codex` (init prints the command when it detects Codex; undo anytime with `hippo hook uninstall codex`).
|
|
116
120
|
|
|
117
121
|
It also registers the current project in Hippo's workspace registry and installs one machine-level daily runner (6:15am). That runner sweeps every registered workspace, runs `hippo learn --git --days 1`, then `hippo sleep`. You get strict daily consolidation without creating one OS task per project.
|
|
118
122
|
|
|
@@ -696,10 +700,11 @@ On `heartbeat`, `block`, `review` and `complete`, a given `--run` is checked aga
|
|
|
696
700
|
| Framework | Detected by | Patches |
|
|
697
701
|
|-----------|------------|---------|
|
|
698
702
|
| Claude Code | `CLAUDE.md` or `.claude/settings.json` | `CLAUDE.md` + `SessionStart`/`SessionEnd` hooks in `settings.json` |
|
|
699
|
-
| Codex | `AGENTS.md` or `.codex` | `AGENTS.md
|
|
703
|
+
| Codex | `AGENTS.md` or `.codex` | `AGENTS.md`; session capture is opt-in with `hippo hook install codex`, which wraps the Codex launcher |
|
|
700
704
|
| Cursor | `.cursorrules` or `.cursor/rules` | `.cursorrules` |
|
|
701
705
|
| OpenClaw | `.openclaw` or `AGENTS.md` | native OpenClaw plugin or `AGENTS.md` |
|
|
702
706
|
| OpenCode | `.opencode/` or `opencode.json` | `AGENTS.md` + TS plugin at `~/.config/opencode/plugins/hippo.ts` (subscribes to `session.idle` + `session.created`) |
|
|
707
|
+
| Pi | `.pi` or `.pi/agent` | `AGENTS.md`; copy the [Pi extension](https://github.com/kitfunso/hippo-memory/tree/master/extensions/pi-extension) for session hooks |
|
|
703
708
|
|
|
704
709
|
No extra commands needed. Just `hippo init` and your agent knows about Hippo.
|
|
705
710
|
|
|
@@ -825,17 +830,17 @@ For how these mechanisms connect to LLM training, continual learning, and open r
|
|
|
825
830
|
|
|
826
831
|
## Comparison
|
|
827
832
|
|
|
828
|
-
The AI-memory category matured fast in 2026. Hippo's specific take — bio-decay, strengthen-on-use, outcome-weighted half-lives — is one stance among several. The table below is a feature snapshot, not a verdict: graph-first systems ([gbrain](https://hermesatlas.com/projects/garrytan/gbrain), [Zep](https://www.getzep.com/), [Cognee](https://www.cognee.ai/)), agent-managed systems ([Letta](https://github.com/letta-ai/letta)), and version-control / skill-distillation takes ([Memoria](https://github.com/matrixorigin/Memoria), [EverMind](https://evermind.ai/)) all solve adjacent problems with different mechanics.
|
|
833
|
+
The AI-memory category matured fast in 2026. Hippo's specific take — bio-decay, strengthen-on-use, outcome-weighted half-lives — is one stance among several. The table below is a feature snapshot, not a verdict: graph-first systems ([gbrain](https://hermesatlas.com/projects/garrytan/gbrain), [Zep](https://www.getzep.com/), [Cognee](https://www.cognee.ai/)), agent-managed systems ([Letta](https://github.com/letta-ai/letta-code)), and version-control / skill-distillation takes ([Memoria](https://github.com/matrixorigin/Memoria), [EverMind](https://evermind.ai/)) all solve adjacent problems with different mechanics.
|
|
829
834
|
|
|
830
|
-
| Feature | Hippo | [MemPalace](https://github.com/milla-jovovich/mempalace) | [Mem0](https://github.com/mem0ai/mem0) | [Basic Memory](https://github.com/basicmachines-co/basic-memory) | [gbrain](https://hermesatlas.com/projects/garrytan/gbrain) | [Zep](https://www.getzep.com/) | [Letta](https://github.com/letta-ai/letta) | [Cognee](https://www.cognee.ai/) | [Memoria](https://github.com/matrixorigin/Memoria) | [EverMind](https://evermind.ai/) |
|
|
835
|
+
| Feature | Hippo | [MemPalace](https://github.com/milla-jovovich/mempalace) | [Mem0](https://github.com/mem0ai/mem0) | [Basic Memory](https://github.com/basicmachines-co/basic-memory) | [gbrain](https://hermesatlas.com/projects/garrytan/gbrain) | [Zep](https://www.getzep.com/) | [Letta](https://github.com/letta-ai/letta-code) | [Cognee](https://www.cognee.ai/) | [Memoria](https://github.com/matrixorigin/Memoria) | [EverMind](https://evermind.ai/) |
|
|
831
836
|
|---------|-------|-----------|------|-------------|--------|-----|-------|--------|---------|----------|
|
|
832
837
|
| Decay by default | Yes | No | No | No | No | No | No | No | No | No |
|
|
833
838
|
| Retrieval strengthening | Yes | No | No | No | No | No | No | Partial (recall tuning) | No | Partial (Skill Memory distills patterns) |
|
|
834
839
|
| Reward-proportional decay | Yes | No | No | No | No | No | No | No | No | No |
|
|
835
|
-
| Hybrid search (BM25 + embeddings) | Yes | Embeddings + spatial |
|
|
836
|
-
| Schema acceleration / knowledge graph | Yes (schema) | No |
|
|
837
|
-
| Conflict detection + resolution | Yes | No |
|
|
838
|
-
| Multi-agent shared memory | Yes | No | No | No | Yes (brain repo, team mounts) | Yes |
|
|
840
|
+
| Hybrid search (BM25 + embeddings) | Yes | Embeddings + spatial | Yes (semantic + BM25 + entity) | No | Yes (vec + rerank + graph) | Yes (graph + vec) | ? | Yes (GraphRAG) | Yes (vector + full-text) | Yes (mRAG, multi-modal) |
|
|
841
|
+
| Schema acceleration / knowledge graph | Yes (schema) | No | Partial (entity linking; graph memory on Pro) | No | Yes (typed KG, self-wiring) | Yes (temporal KG) | No | Yes (auto-ontologies) | No (typed claims) | Yes (hierarchical: user/group/agent) |
|
|
842
|
+
| Conflict detection + resolution | Yes | No | Partial (hosted platform marks superseded facts) | No | Yes (eval-surfaced) | Yes (auto-invalidate stale facts) | No | No | Yes (auto-detect + quarantine) | Partial (temporal tracking) |
|
|
843
|
+
| Multi-agent shared memory | Yes | No | No | No | Yes (brain repo, team mounts) | Yes | Yes (shared memory blocks) | Yes | Yes (branch/merge across sessions) | Yes (multi-agent coordination) |
|
|
839
844
|
| Transfer scoring | Yes | No | No | No | No | No | No | No | No | No |
|
|
840
845
|
| Outcome tracking | Yes | No | No | No | No | No | No | No | No | Partial (Cases: agent trajectories) |
|
|
841
846
|
| Confidence tiers | Yes | No | No | No | No (typed facts) | No | No | No | No | No |
|
|
@@ -843,16 +848,16 @@ The AI-memory category matured fast in 2026. Hippo's specific take — bio-decay
|
|
|
843
848
|
| Lossless compression | No | Yes (AAAK, 30x) | No | No | No | No | No | No | No | No |
|
|
844
849
|
| Cross-tool import (ChatGPT/Claude/Cursor) | Yes | No | No | No | Partial (data sources) | ? | No | Partial (28 data sources) | No (Git ops) | Partial (mRAG: PDFs/images/URLs) |
|
|
845
850
|
| Auto-hook install | Yes | No | No | No | No | No | No | No | No | No |
|
|
846
|
-
| MCP server | Yes | Yes |
|
|
847
|
-
| Zero runtime deps | Yes | No (ChromaDB) | No | No | No (PGLite or PG+pgvector) | No (managed service) | No (
|
|
848
|
-
| LongMemEval (best published) | 98.0% local / 99.8% voyage R@5 (s_cleaned, per-haystack)\* | 96.6% raw / 100% reranked R@5 |
|
|
849
|
-
| Git-friendly | Yes | No | No | Yes | Yes | No |
|
|
851
|
+
| MCP server | Yes | Yes | Yes (hosted, needs an account) | Yes | Yes (stdio + HTTP/OAuth) | Yes (hosted, needs an account) | Yes (hosted, needs an API key) | Yes (first-party Claude/LangGraph) | Yes | ? |
|
|
852
|
+
| Zero runtime deps | Yes | No (ChromaDB) | No | No | No (PGLite or PG+pgvector) | No (managed service) | No (npm deps) | No (Python deps) | Yes (single Rust binary) | No (managed + OSS) |
|
|
853
|
+
| LongMemEval (best published) | 98.0% local / 99.8% voyage R@5 (s_cleaned, per-haystack)\* | 96.6% raw / 100% reranked R@5 | 94.4 (hosted platform)\*\* | N/A | 97.6-97.9% R@5 (s_cleaned\*) | 90.2% accuracy\*\* (LoCoMo 94.7%) | N/A | N/A | 88.78% overall accuracy w/ reader\*\* | 83.00% overall\*\* (LoCoMo 93.05%, HaluMem 93.04%) |
|
|
854
|
+
| Git-friendly | Yes | No | No | Yes | Yes | No | Yes (memory tracked in git) | No | Yes (Git is the model) | ? |
|
|
850
855
|
| Framework agnostic | Yes | Yes | Partial | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
|
|
851
|
-
| License | MIT | (open) | Apache-2.0 | (open) | MIT | Apache-2.0
|
|
856
|
+
| License | MIT | (open) | Apache-2.0 | (open) | MIT | Proprietary cloud (Graphiti: Apache-2.0) | Apache-2.0 | MIT (core) | Apache-2.0 | Apache-2.0 (OSS) + cloud |
|
|
852
857
|
|
|
853
858
|
\* Hippo's 98.0% uses the free local MiniLM embedder (an optional install) and 99.8% uses voyage-3-large (measured 2026-06-09, not re-run). Both are on `longmemeval_s_cleaned` with a per-question haystack, the split and metric of gbrain's published 97.6%. Each is the best of five retrieval settings in the benchmark scripts, not `hippo recall`. At 500 questions the 95% interval is about ±1.2 points, so 98.0 and 97.6 are a tie. The June 2026 build scored 98.6; [`docs/evals/2026-09-23-longmemeval-reproduction.md`](docs/evals/2026-09-23-longmemeval-reproduction.md) has both runs. An older hippo number, 86.8% R@5 on `longmemeval_oracle` under pooled (non-per-haystack) retrieval, is not comparable to per-haystack figures.
|
|
854
859
|
|
|
855
|
-
\*\* Different metric: Memoria's 88.78% and EverMind's 83% are
|
|
860
|
+
\*\* Different metric: these are end-to-end answer scores, not retrieval R@5. Mem0's 94.4 comes from its hosted platform, which its README says includes optimizations the open-source SDK lacks. Zep's 90.2% and 94.7% are accuracy figures from its homepage. Memoria's 88.78% and EverMind's 83% are overall accuracy with a reader LLM. Higher denominator + LLM helps. Not directly comparable to retrieval-only R@5 numbers above. The Mem0, Zep and Letta columns were last checked against each vendor's own pages on 2026-09-28.
|
|
856
861
|
|
|
857
862
|
Different tools answer different questions. Mem0 and Basic Memory implement "save everything, search later." MemPalace implements "store everything, organize spatially for retrieval." gbrain, Zep, and Cognee implement "extract typed entities and relationships into a knowledge graph." Letta implements "the agent edits its own memory blocks." Memoria implements "Git-style version control over the memory state itself." EverMind implements "self-evolving Skill Memory + multi-modal retrieval over hierarchical scopes." Hippo implements "learn what is wrong and stop repeating it." These are complementary takes, not a single-axis ranking: bio-lifecycle (Hippo) + GraphRAG (gbrain/Cognee/Zep) + agent-self-edit (Letta) + memory-VCS (Memoria) + skill-distillation (EverMind) cover different parts of the same problem.
|
|
858
863
|
|
|
@@ -950,6 +955,54 @@ node run.mjs --adapter all
|
|
|
950
955
|
|
|
951
956
|
---
|
|
952
957
|
|
|
958
|
+
## FAQ
|
|
959
|
+
|
|
960
|
+
### How do I give Claude Code memory between sessions?
|
|
961
|
+
|
|
962
|
+
Run `npm install -g hippo-memory`, then `hippo init` in the project, or `hippo init --scan ~` for every repo on the machine. If the project has a `CLAUDE.md`, init adds a short block telling Claude to run `hippo context --auto` when a session starts. It also adds hooks to Claude Code's settings that keep your pinned memories in context, save a task snapshot before compaction, and run `hippo sleep` when the session ends. The [Claude Code plugin](https://github.com/kitfunso/hippo-memory/tree/master/extensions/claude-code-plugin) is the alternative to these hooks; use one, not both.
|
|
963
|
+
|
|
964
|
+
### How do I give Cursor memory between sessions?
|
|
965
|
+
|
|
966
|
+
`hippo init` adds its instructions to `.cursorrules` if the project has one, and the [MCP server](#mcp-server) gives Cursor's agent tools to recall and store memories once you add `hippo mcp` to `.cursor/mcp.json`. `hippo import --cursor .cursorrules` turns your existing rules into memories.
|
|
967
|
+
|
|
968
|
+
### How do I give Codex memory across sessions?
|
|
969
|
+
|
|
970
|
+
`hippo init` adds its instructions to your `AGENTS.md`, which Codex reads before it starts work. Capturing Codex sessions is opt-in: `hippo hook install codex` wraps the Codex launcher, and `hippo hook uninstall codex` removes the wrapper.
|
|
971
|
+
|
|
972
|
+
### Which agents does hippo work with?
|
|
973
|
+
|
|
974
|
+
`hippo init` detects Claude Code, Codex, Cursor, OpenClaw, OpenCode and Pi, and wires itself into each one's instruction file, hooks or plugin. It only patches instruction files that already exist. Any MCP client can use the [MCP server](#mcp-server), and other tools can call the CLI or the HTTP API that `hippo serve` starts.
|
|
975
|
+
|
|
976
|
+
### Can I use hippo as an MCP memory server?
|
|
977
|
+
|
|
978
|
+
Yes. `hippo mcp` runs the server over stdio, and `npx -y hippo-memory mcp` runs it without a global install. Add it to the MCP config of Claude Desktop, Cursor, Windsurf, Cline or any other client (example [above](#mcp-server)); in Claude Code, run `claude mcp add hippo-memory -- hippo mcp`. The agent gets tools such as `hippo_recall`, `hippo_remember` and `hippo_outcome`.
|
|
979
|
+
|
|
980
|
+
### How is hippo different from mem0?
|
|
981
|
+
|
|
982
|
+
mem0 uses a language model to extract memories, OpenAI by default in its open-source library, and memories stored through its hosted MCP server live in your Mem0 account ([mem0 docs](https://docs.mem0.ai/platform/mem0-mcp), checked 2026-09-28). Hippo stores memories in SQLite on your machine, needs no account and no model, and `hippo init` wires it into the coding agents it finds. mem0's platform and hippo both mark an older fact superseded when a newer one replaces it. Hippo also lets you mark a recalled memory wrong with `hippo outcome --bad`, and it drops out of the top results.
|
|
983
|
+
|
|
984
|
+
### Do I still need CLAUDE.md?
|
|
985
|
+
|
|
986
|
+
Yes, for short standing rules such as build commands, code style and things never to do. Claude Code loads `CLAUDE.md` and its auto memory into every session, and its [memory docs](https://code.claude.com/docs/en/memory) say that when two rules contradict each other, Claude may pick one arbitrarily. Hippo holds the lessons that pile up, recalls the ones that match the task, and retires the ones marked wrong or replaced. `hippo init` adds its block to `CLAUDE.md`, and `hippo import --claude CLAUDE.md` turns existing notes into memories.
|
|
987
|
+
|
|
988
|
+
### What happens when a memory turns out to be wrong?
|
|
989
|
+
|
|
990
|
+
Mark it, and it stops coming back. `hippo outcome --bad` weakens the memories from the last recall, `hippo supersede <id> "<new fact>"` replaces one with a newer version, and `hippo reject <id> --reason "<why>"` stops that value from returning at all. On the synthetic E1 test, where every mark is correct, plain BM25 plus the outcome mark cut how often a marked-bad memory stayed in the top five from 71.9% to 0.0%. Real marks are noisier, because `--bad` marks the whole recall batch.
|
|
991
|
+
|
|
992
|
+
### Where does hippo keep my data?
|
|
993
|
+
|
|
994
|
+
On your machine, in SQLite: `.hippo/hippo.db` in each project, plus a global store in `~/.hippo/` for lessons shared across projects, with markdown mirrors you can read and commit. Recall makes no network call by default. Text goes to an outside provider only through features that use one: an API embedder, the Jev or LLM reranker, `hippo refine`, and the fact extraction `hippo sleep` runs through Anthropic's API whenever `ANTHROPIC_API_KEY` is set in its environment. To turn that last one off, set `{"extraction":{"enabled":false}}` in `.hippo/config.json`.
|
|
995
|
+
|
|
996
|
+
### What does hippo cost?
|
|
997
|
+
|
|
998
|
+
Nothing. Hippo is MIT-licensed and needs no account or API key. Optional features that call an outside provider bill through it: the Jev reranker costs about 0.0004 USD a recall, and API embedders and sleep's fact extraction bill your own keys. Memory text handed to your agent uses context tokens, and `hippo tokens` shows how many.
|
|
999
|
+
|
|
1000
|
+
### Has hippo been shown to make agents better at their work?
|
|
1001
|
+
|
|
1002
|
+
Not yet. The published numbers measure retrieval: whether the right memory comes back, and whether a memory marked wrong stays out of the results. The paired test that runs real agent sessions with and without hippo has not had a scored run yet. Every measurement, including failed runs and one retracted claim, is indexed in [docs/evals](https://github.com/kitfunso/hippo-memory/blob/master/docs/evals/README.md).
|
|
1003
|
+
|
|
1004
|
+
---
|
|
1005
|
+
|
|
953
1006
|
## Contributing
|
|
954
1007
|
|
|
955
1008
|
Issues and PRs welcome. Before contributing, run `hippo status` in the repo root to see the project's own memory.
|
package/dist/cli.d.ts
CHANGED
|
@@ -65,5 +65,7 @@ export declare function printContextMarkdown(items: Array<{
|
|
|
65
65
|
showStrength?: boolean;
|
|
66
66
|
heading?: string;
|
|
67
67
|
}): void;
|
|
68
|
+
export declare function usageText(): string;
|
|
69
|
+
export declare function verbUsage(verb: string): string | null;
|
|
68
70
|
export declare function runCli(argv?: string[]): Promise<void>;
|
|
69
71
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.js
CHANGED
|
@@ -138,7 +138,7 @@ import { listDlq, replayDlqEntry } from './connectors/slack/dlq.js';
|
|
|
138
138
|
import { backfillChannel } from './connectors/slack/backfill.js';
|
|
139
139
|
import { slackHistoryFetcher } from './connectors/slack/web-client.js';
|
|
140
140
|
import { addWorkspace as addSlackWorkspace, listWorkspaces as listSlackWorkspaces, removeWorkspace as removeSlackWorkspace, } from './connectors/slack/workspaces.js';
|
|
141
|
-
import { cmdGithub } from './connectors/github/cli-impl.js';
|
|
141
|
+
import { cmdGithub, printGithubBackfillUsage } from './connectors/github/cli-impl.js';
|
|
142
142
|
// ---------------------------------------------------------------------------
|
|
143
143
|
// Helpers
|
|
144
144
|
// ---------------------------------------------------------------------------
|
|
@@ -392,6 +392,11 @@ export function parseArgs(argv) {
|
|
|
392
392
|
i += 2;
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
|
+
else if (part === '-h') {
|
|
396
|
+
// Running a verb when help was asked costs more than losing a literal -h; `-- -h` still passes one.
|
|
397
|
+
flags['help'] = true;
|
|
398
|
+
i++;
|
|
399
|
+
}
|
|
395
400
|
else {
|
|
396
401
|
args.push(part);
|
|
397
402
|
i++;
|
|
@@ -8168,10 +8173,6 @@ function printAuditPruneUsage() {
|
|
|
8168
8173
|
console.log(' --json Output the result as JSON {cutoff, count, dryRun}.');
|
|
8169
8174
|
}
|
|
8170
8175
|
function cmdAuditPrune(hippoRoot, flags) {
|
|
8171
|
-
if (flags['help']) {
|
|
8172
|
-
printAuditPruneUsage();
|
|
8173
|
-
return;
|
|
8174
|
-
}
|
|
8175
8176
|
const olderThanRaw = typeof flags['older-than'] === 'string' ? flags['older-than'] : '';
|
|
8176
8177
|
if (!olderThanRaw) {
|
|
8177
8178
|
console.error('Usage: hippo audit prune --older-than <Nd> [--dry-run] [--tenant <t>]');
|
|
@@ -8474,12 +8475,6 @@ function printSlackBackfillUsage() {
|
|
|
8474
8475
|
console.log(' --since backfill from ISO timestamp (default: cursor)');
|
|
8475
8476
|
}
|
|
8476
8477
|
function cmdSlackBackfill(hippoRoot, flags) {
|
|
8477
|
-
// M3: detect --help BEFORE token check so operators can read usage in
|
|
8478
|
-
// environments without SLACK_BOT_TOKEN configured.
|
|
8479
|
-
if (flags['help']) {
|
|
8480
|
-
printSlackBackfillUsage();
|
|
8481
|
-
return;
|
|
8482
|
-
}
|
|
8483
8478
|
const channel = typeof flags['channel'] === 'string' ? flags['channel'] : undefined;
|
|
8484
8479
|
if (!channel) {
|
|
8485
8480
|
printSlackBackfillUsage();
|
|
@@ -8557,10 +8552,6 @@ function printSlackWorkspacesUsage() {
|
|
|
8557
8552
|
console.log(' remove --team <T> Remove a workspace registration');
|
|
8558
8553
|
}
|
|
8559
8554
|
function cmdSlackWorkspacesAdd(hippoRoot, flags) {
|
|
8560
|
-
if (flags['help']) {
|
|
8561
|
-
printSlackWorkspacesUsage();
|
|
8562
|
-
return;
|
|
8563
|
-
}
|
|
8564
8555
|
const teamId = typeof flags['team'] === 'string' ? flags['team'].trim() : '';
|
|
8565
8556
|
const tenantId = typeof flags['tenant'] === 'string' ? flags['tenant'].trim() : '';
|
|
8566
8557
|
if (!teamId || !tenantId) {
|
|
@@ -8593,10 +8584,6 @@ function cmdSlackWorkspacesList(hippoRoot) {
|
|
|
8593
8584
|
}
|
|
8594
8585
|
}
|
|
8595
8586
|
function cmdSlackWorkspacesRemove(hippoRoot, flags) {
|
|
8596
|
-
if (flags['help']) {
|
|
8597
|
-
printSlackWorkspacesUsage();
|
|
8598
|
-
return;
|
|
8599
|
-
}
|
|
8600
8587
|
const teamId = typeof flags['team'] === 'string' ? flags['team'].trim() : '';
|
|
8601
8588
|
if (!teamId) {
|
|
8602
8589
|
console.error('Usage: hippo slack workspaces remove --team <T>');
|
|
@@ -8649,9 +8636,9 @@ function cmdSlack(hippoRoot, args, flags) {
|
|
|
8649
8636
|
console.error('Usage: hippo slack <backfill|dlq list|dlq replay <id> [--force]|workspaces add|workspaces list|workspaces remove> [...]');
|
|
8650
8637
|
process.exit(1);
|
|
8651
8638
|
}
|
|
8652
|
-
function
|
|
8653
|
-
|
|
8654
|
-
Hippo -
|
|
8639
|
+
export function usageText() {
|
|
8640
|
+
return `
|
|
8641
|
+
Hippo - memory for AI agents that learns what is wrong and stops repeating it
|
|
8655
8642
|
|
|
8656
8643
|
Usage: hippo <command> [options]
|
|
8657
8644
|
|
|
@@ -8671,6 +8658,10 @@ Commands:
|
|
|
8671
8658
|
--observed Set confidence: observed
|
|
8672
8659
|
--inferred Set confidence: inferred
|
|
8673
8660
|
--global Store in global store ($HIPPO_HOME or ~/.hippo/)
|
|
8661
|
+
supersede <id> "<text>" Replace a memory with a new version; the old one points at it
|
|
8662
|
+
--layer <layer> Layer for the new memory (default: the old memory's layer)
|
|
8663
|
+
--tag <tag> Tag for the new memory (repeatable; default: the old memory's tags)
|
|
8664
|
+
--pin Pin the new memory (default: pinned if the old one was)
|
|
8674
8665
|
recall <query> Search and retrieve memories (local + global)
|
|
8675
8666
|
--budget <n> Token budget (default: 4000)
|
|
8676
8667
|
--min-results <n> Minimum results regardless of budget (default: 1)
|
|
@@ -8806,9 +8797,19 @@ Commands:
|
|
|
8806
8797
|
dlq list List DLQ entries for the active tenant
|
|
8807
8798
|
dlq replay <id> [--force]
|
|
8808
8799
|
Re-ingest a DLQ entry (--force skips sig check)
|
|
8800
|
+
slack Slack connector subcommands (backfill, dlq, workspaces)
|
|
8801
|
+
backfill --channel <id> [--since ISO]
|
|
8802
|
+
Backfill a channel's history (needs SLACK_BOT_TOKEN)
|
|
8803
|
+
dlq list List DLQ entries for the active tenant
|
|
8804
|
+
dlq replay <id> [--force]
|
|
8805
|
+
Re-ingest a DLQ entry (--force skips sig check)
|
|
8806
|
+
workspaces <add|list|remove>
|
|
8807
|
+
Map Slack workspaces (team ids) to tenants
|
|
8809
8808
|
provenance Provenance coverage gate for kind='raw' rows
|
|
8810
8809
|
--json Output as JSON
|
|
8811
8810
|
--strict Exit non-zero when coverage < 100%
|
|
8811
|
+
dag Show the summary tree: entity profiles, topic summaries, facts
|
|
8812
|
+
--stats Count memories per DAG level instead
|
|
8812
8813
|
drill <summary-id> Walk down a DAG level-2 summary to its children
|
|
8813
8814
|
--limit N Cap children list (default 50)
|
|
8814
8815
|
--budget N Cap total child token cost (≈ chars/4)
|
|
@@ -8999,6 +9000,8 @@ Commands:
|
|
|
8999
9000
|
last-sleep Print the last 'hippo sleep --log-file' output and clear it
|
|
9000
9001
|
--path <p> Log path (default: ~/.hippo/logs/last-sleep.log)
|
|
9001
9002
|
--keep Print without clearing
|
|
9003
|
+
session-end SessionEnd hook: run sleep, then capture this session, in a detached worker
|
|
9004
|
+
--log-file <path> Tee the worker's output to a log file (paired with 'hippo last-sleep')
|
|
9002
9005
|
pre-compact PreCompact hook: save a working-state snapshot before compaction
|
|
9003
9006
|
--log-file <p> Diagnostic log path (default: ~/.hippo/logs/pre-compact.log)
|
|
9004
9007
|
compact-resume SessionStart(compact) hook: re-print the snapshot + session trail
|
|
@@ -9013,6 +9016,20 @@ Commands:
|
|
|
9013
9016
|
SessionStart(compact) for mid-session continuity;
|
|
9014
9017
|
codex wraps the detected launcher in place
|
|
9015
9018
|
hook uninstall <target> Remove hook
|
|
9019
|
+
predict "<claim>" Record a prediction to score against the actual outcome later
|
|
9020
|
+
--class <c> Reference class (required)
|
|
9021
|
+
--estimate <v> Numeric estimate
|
|
9022
|
+
--unit <u> Unit of the estimate
|
|
9023
|
+
--target <YYYY-MM-DD> When the outcome is due
|
|
9024
|
+
predict close <id> Close a prediction
|
|
9025
|
+
--state <s> closed | closed-unknown (required)
|
|
9026
|
+
--actual <v> The actual value
|
|
9027
|
+
--note "<text>" Closure note
|
|
9028
|
+
predict list [--class <c>] [--status open|closed|closed-unknown|all] [--limit N]
|
|
9029
|
+
List predictions (closed and closed-unknown need --class)
|
|
9030
|
+
predict show <id> Show one prediction
|
|
9031
|
+
predict baserate --class <c>
|
|
9032
|
+
How past estimates in a class compared with the actuals
|
|
9016
9033
|
decide "<decision>" Record a decision (first-class object + memory mirror)
|
|
9017
9034
|
--context "<why>" Why this decision was made
|
|
9018
9035
|
--supersedes <mem-id> Supersede the decision backed by this memory id
|
|
@@ -9124,6 +9141,9 @@ Commands:
|
|
|
9124
9141
|
dashboard Open web dashboard for memory health
|
|
9125
9142
|
--port <n> Port to serve on (default: 3333)
|
|
9126
9143
|
mcp Start MCP server (stdio transport)
|
|
9144
|
+
serve Start the HTTP API server for this store (Ctrl+C stops it)
|
|
9145
|
+
--port <n> Port to serve on (default: $HIPPO_PORT or 6789)
|
|
9146
|
+
--host <host> Address to bind (default: 127.0.0.1)
|
|
9127
9147
|
goal <sub> dlPFC goal stack (B3) — scoped per session
|
|
9128
9148
|
goal push <name> Push a new active goal; prints the new goal id
|
|
9129
9149
|
--policy <type> schema-fit-biased | error-prioritized |
|
|
@@ -9221,7 +9241,40 @@ Examples:
|
|
|
9221
9241
|
hippo sleep --dry-run
|
|
9222
9242
|
hippo outcome --good
|
|
9223
9243
|
hippo status
|
|
9224
|
-
|
|
9244
|
+
`;
|
|
9245
|
+
}
|
|
9246
|
+
function printUsage() {
|
|
9247
|
+
console.log(usageText());
|
|
9248
|
+
}
|
|
9249
|
+
const USAGE_ALIASES = new Map([['project-brief', 'brief'], ['customer-note', 'note']]);
|
|
9250
|
+
// Cut from usageText() so a verb's help can never drift from the full listing.
|
|
9251
|
+
export function verbUsage(verb) {
|
|
9252
|
+
const name = USAGE_ALIASES.get(verb) ?? verb;
|
|
9253
|
+
const block = [];
|
|
9254
|
+
let inBlock = false;
|
|
9255
|
+
for (const line of usageText().split('\n')) {
|
|
9256
|
+
if (/^ {2}\S/.test(line))
|
|
9257
|
+
inBlock = line.trimStart().split(' ', 1)[0] === name;
|
|
9258
|
+
else if (!line.startsWith(' '))
|
|
9259
|
+
inBlock = false;
|
|
9260
|
+
if (inBlock)
|
|
9261
|
+
block.push(line);
|
|
9262
|
+
}
|
|
9263
|
+
return block.length > 0 ? block.join('\n') : null;
|
|
9264
|
+
}
|
|
9265
|
+
// These sub-commands have fuller usage text than their lines in usageText().
|
|
9266
|
+
const SUBCOMMAND_USAGE = new Map([
|
|
9267
|
+
['audit prune', printAuditPruneUsage],
|
|
9268
|
+
['slack backfill', printSlackBackfillUsage],
|
|
9269
|
+
['slack workspaces', printSlackWorkspacesUsage],
|
|
9270
|
+
['github backfill', printGithubBackfillUsage],
|
|
9271
|
+
]);
|
|
9272
|
+
function printHelp(command, args) {
|
|
9273
|
+
const printSubcommandUsage = SUBCOMMAND_USAGE.get(`${command} ${args[0] ?? ''}`);
|
|
9274
|
+
if (printSubcommandUsage)
|
|
9275
|
+
printSubcommandUsage();
|
|
9276
|
+
else
|
|
9277
|
+
console.log(verbUsage(command) ?? usageText());
|
|
9225
9278
|
}
|
|
9226
9279
|
// ---------------------------------------------------------------------------
|
|
9227
9280
|
// Entry point
|
|
@@ -9235,6 +9288,15 @@ async function main(command, args, flags, hippoRoot) {
|
|
|
9235
9288
|
console.log(version);
|
|
9236
9289
|
process.exit(0);
|
|
9237
9290
|
}
|
|
9291
|
+
if (command === '' || command === 'help' || command === '--help' || command === '-h') {
|
|
9292
|
+
printUsage();
|
|
9293
|
+
return;
|
|
9294
|
+
}
|
|
9295
|
+
// Before every other step, so help never opens a store, installs a hook or starts a server.
|
|
9296
|
+
if (Object.hasOwn(flags, 'help')) {
|
|
9297
|
+
printHelp(command, args);
|
|
9298
|
+
return;
|
|
9299
|
+
}
|
|
9238
9300
|
maybeRepairCodexWrapper(command, flags);
|
|
9239
9301
|
/** Global --scope well-formedness guard (v1.26.2). parseArgs stores a value-less
|
|
9240
9302
|
* flag as boolean true; downstream the 14 consumer sites either coerced that to
|
|
@@ -10092,12 +10154,6 @@ async function main(command, args, flags, hippoRoot) {
|
|
|
10092
10154
|
case 'graph':
|
|
10093
10155
|
cmdGraph(hippoRoot, args, flags);
|
|
10094
10156
|
break;
|
|
10095
|
-
case 'help':
|
|
10096
|
-
case '--help':
|
|
10097
|
-
case '-h':
|
|
10098
|
-
case '':
|
|
10099
|
-
printUsage();
|
|
10100
|
-
break;
|
|
10101
10157
|
default:
|
|
10102
10158
|
console.error(`Unknown command: ${command}`);
|
|
10103
10159
|
printUsage();
|
|
@@ -64,10 +64,6 @@ export function printGithubBackfillUsage() {
|
|
|
64
64
|
* code path without hitting the network. Defaults to `realGitHubFetcher`.
|
|
65
65
|
*/
|
|
66
66
|
export async function cmdGithubBackfill(hippoRoot, flags, fetcher = realGitHubFetcher) {
|
|
67
|
-
if (flags['help']) {
|
|
68
|
-
printGithubBackfillUsage();
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
67
|
const repo = flags['repo'];
|
|
72
68
|
if (!isFlagString(repo) || !repo.includes('/')) {
|
|
73
69
|
printGithubBackfillUsage();
|
package/dist/version.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* an ESM `import` can resolve cleanly, and a hardcoded constant survives
|
|
17
17
|
* any packager that drops .json files.
|
|
18
18
|
*/
|
|
19
|
-
export declare const PACKAGE_VERSION = "1.52.
|
|
19
|
+
export declare const PACKAGE_VERSION = "1.52.5";
|
|
20
20
|
/** Compares plain x.y.z versions, positive if a > b; tags throw so the rollback guard never misfires silently. */
|
|
21
21
|
export declare function compareSemver(a: string, b: string): number;
|
|
22
22
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* an ESM `import` can resolve cleanly, and a hardcoded constant survives
|
|
17
17
|
* any packager that drops .json files.
|
|
18
18
|
*/
|
|
19
|
-
export const PACKAGE_VERSION = '1.52.
|
|
19
|
+
export const PACKAGE_VERSION = '1.52.5';
|
|
20
20
|
/** Compares plain x.y.z versions, positive if a > b; tags throw so the rollback guard never misfires silently. */
|
|
21
21
|
export function compareSemver(a, b) {
|
|
22
22
|
const parse = (v) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "hippo-memory",
|
|
3
3
|
"name": "Hippo Memory",
|
|
4
|
-
"description": "
|
|
5
|
-
"version": "1.52.
|
|
4
|
+
"description": "Memory for AI agents that learns what is wrong and stops repeating it. Injects context at session start and captures errors.",
|
|
5
|
+
"version": "1.52.5",
|
|
6
6
|
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "hippo-memory",
|
|
3
3
|
"name": "Hippo Memory",
|
|
4
|
-
"description": "
|
|
5
|
-
"version": "1.52.
|
|
4
|
+
"description": "Memory for AI agents that learns what is wrong and stops repeating it. Injects context at session start and captures errors.",
|
|
5
|
+
"version": "1.52.5",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hippo-memory",
|
|
3
|
-
"version": "1.52.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.52.5",
|
|
4
|
+
"description": "Memory for AI agents that learns what is wrong and stops repeating it. MCP server and hooks for Claude Code, Codex and Cursor. SQLite, zero runtime deps.",
|
|
5
5
|
"mcpName": "io.github.kitfunso/hippo-memory",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -46,26 +46,34 @@
|
|
|
46
46
|
},
|
|
47
47
|
"keywords": [
|
|
48
48
|
"memory",
|
|
49
|
-
"ai",
|
|
50
|
-
"agents",
|
|
51
|
-
"llm",
|
|
52
|
-
"claude",
|
|
53
|
-
"context",
|
|
54
|
-
"recall",
|
|
55
|
-
"episodic",
|
|
56
|
-
"semantic",
|
|
57
|
-
"embeddings",
|
|
58
|
-
"hybrid-search",
|
|
59
49
|
"agent-memory",
|
|
50
|
+
"ai-memory",
|
|
51
|
+
"llm-memory",
|
|
60
52
|
"long-term-memory",
|
|
53
|
+
"persistent-memory",
|
|
54
|
+
"memory-layer",
|
|
61
55
|
"mcp",
|
|
56
|
+
"mcp-server",
|
|
62
57
|
"model-context-protocol",
|
|
63
58
|
"claude-code",
|
|
59
|
+
"claude",
|
|
60
|
+
"codex",
|
|
61
|
+
"cursor",
|
|
62
|
+
"openclaw",
|
|
63
|
+
"opencode",
|
|
64
|
+
"ai-agents",
|
|
65
|
+
"coding-agent",
|
|
66
|
+
"agents",
|
|
67
|
+
"llm",
|
|
64
68
|
"rag",
|
|
65
69
|
"retrieval",
|
|
70
|
+
"hybrid-search",
|
|
71
|
+
"embeddings",
|
|
66
72
|
"sqlite",
|
|
73
|
+
"local-first",
|
|
67
74
|
"cli",
|
|
68
|
-
"
|
|
75
|
+
"context",
|
|
76
|
+
"recall"
|
|
69
77
|
],
|
|
70
78
|
"author": "Keith",
|
|
71
79
|
"license": "MIT",
|