hippo-memory 1.54.0 → 1.55.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/README.md +5 -5
- package/dist/cli.js +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +1 -1
- package/dist/session-digest.js +1 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,7 +118,7 @@ Run `hippo init` inside one project. This is everything it writes, in the projec
|
|
|
118
118
|
- **Instruction files.** A block between `<!-- hippo:start -->` and `<!-- hippo:end -->` in the project's `CLAUDE.md` or `AGENTS.md`, only if that file already exists. Codex, Cursor, OpenClaw, OpenCode and Pi read `AGENTS.md`.
|
|
119
119
|
- **Claude Code,** when the project has `CLAUDE.md` or `.claude/settings.json`: 7 hook entries in `~/.claude/settings.json`, one each on SessionEnd, UserPromptSubmit, PreCompact, PostCompact and PostToolUseFailure and two on SessionStart. [Framework Integrations](#framework-integrations) says what each one runs.
|
|
120
120
|
- **OpenCode,** when the project has `.opencode/` or `opencode.json`: a plugin at `~/.config/opencode/plugins/hippo.ts`.
|
|
121
|
-
- **Codex,** when the project has `AGENTS.md` or `.codex` and Codex is installed (`$CODEX_HOME`, else `~/.codex`, exists): 2 hook entries in Codex's `hooks.json`, one on UserPromptSubmit that sends your pinned memories plus
|
|
121
|
+
- **Codex,** when the project has `AGENTS.md` or `.codex` and Codex is installed (`$CODEX_HOME`, else `~/.codex`, exists): 2 hook entries in Codex's `hooks.json`, one on UserPromptSubmit that sends your pinned memories plus up to 5 that match the prompt with every prompt and one on SessionStart after a compaction. **Codex runs them only after you trust them once in `/hooks`.** Init also prints `hippo hook install codex`, the opt-in that wraps the Codex launcher to capture sessions; `hippo hook uninstall codex` removes hippo's hooks and the wrapper.
|
|
122
122
|
- **A daily run at 6:15am,** one per machine: a crontab line on Linux and macOS, a scheduled task named `hippo-daily-runner` on Windows. It runs `hippo learn --git --days 1` and then `hippo sleep` in every project listed in `~/.hippo/workspaces.json`, and init adds this project to that list.
|
|
123
123
|
- **Agent memories.** On every run, the notes your coding agents keep about this project go into its store, and the ones about you go into the global store. [Agent memories](#agent-memories) lists what is read.
|
|
124
124
|
|
|
@@ -783,7 +783,7 @@ The block asks for nothing a hook already does, because each extra tool call re-
|
|
|
783
783
|
For Claude Code, it also adds 7 hook entries to `~/.claude/settings.json`:
|
|
784
784
|
- a `SessionEnd` hook that runs `hippo sleep` and then `hippo capture` when the session exits. Capture matches the last 20 user and 10 assistant messages of the transcript against word patterns for decisions, rules, errors and preferences. It uses no model and does not read earlier turns, so record lessons with `hippo remember` as you go.
|
|
785
785
|
- a `SessionStart` hook that prints the previous session's consolidation output
|
|
786
|
-
- a `UserPromptSubmit` hook that runs `hippo context --pinned-only --include-recent 5 --format additional-context` every turn. It re-injects pinned memories (`hippo remember <text> --pin`) plus
|
|
786
|
+
- a `UserPromptSubmit` hook that runs `hippo context --pinned-only --include-recent 5 --format additional-context` every turn. It re-injects pinned memories (`hippo remember <text> --pin`) plus up to 5 memories that share words with your prompt. When nothing matches, it adds only the pinned ones. Since 1.55.0 this replaces the 5 newest memories, which cut the median block from 847 to 533 tokens in our eval. `{"pinnedInject":{"promptRecall":false}}` brings back the 5 newest, so fresh same-session lessons appear on the next prompt whatever you ask. The block is rendered without live strength percentages, so it stays byte-identical while its memories do not change, and it is sent only when it changed since the session's last prompt: an unchanged block is skipped, resent every 10 skips (`pinnedInject.refreshTurns`, `0` never resends) and resent after compaction. The prompt-matched memories go in a separate block that is never skipped, so they are sent on every prompt they match. `{"pinnedInject":{"skipUnchanged":false}}` sends the pinned block every turn as before. Opt out entirely with `{"pinnedInject":{"enabled":false}}` in `.hippo/config.json`.
|
|
787
787
|
- a `PreCompact` hook that runs `hippo pre-compact` before the transcript gets summarized. It records the compaction in the store, saves a working-state snapshot (task/summary/next step) so mid-session compaction can't drop it, and asks the summariser to end its summary with a "Memories for hippo" list: the lessons, decisions and corrections from the session that should outlive it. The `SessionEnd` hook still owns extracting durable memories from the transcript.
|
|
788
788
|
- a second `SessionStart` hook (matcher `compact`) that runs `hippo compact-resume`, printing that snapshot back into context right after compaction, if it is under 15 minutes old.
|
|
789
789
|
- a `PostCompact` hook that runs `hippo post-compact`. It keeps the summary in the store with secrets scrubbed, and saves each item of that list as a memory that sleep never deletes: at most 10 per compaction, skipping an item an earlier compaction already saved and any item that looks like a secret. An item over 500 characters stays in the compaction's record only. It then prints one line, such as "Hippo saved 3 memories from this compaction and restored your task snapshot." If the store is busy, the summary waits in the store's `compactions-spool/` folder and `hippo sleep` finishes the save; `hippo doctor` names any compaction left unfinished for over 10 minutes. The session that compacted does not have those memories injected back into its own prompts, since it just read them in the summary; `hippo recall` still finds them. The hook prints nothing when there is no store to save to.
|
|
@@ -794,7 +794,7 @@ Only Claude Code saves memories at a compaction: hippo installs no `PreCompact`
|
|
|
794
794
|
To remove: `hippo hook uninstall claude-code`
|
|
795
795
|
|
|
796
796
|
For Codex, it adds two hooks to `$CODEX_HOME/hooks.json` (else `~/.codex/hooks.json`) and keeps every hook already there:
|
|
797
|
-
- a `UserPromptSubmit` hook that runs the same `hippo context --pinned-only` command as Claude Code's, so your pinned memories plus
|
|
797
|
+
- a `UserPromptSubmit` hook that runs the same `hippo context --pinned-only` command as Claude Code's, so your pinned memories plus up to 5 that match the prompt reach every prompt as developer context
|
|
798
798
|
- a `SessionStart` hook (matcher `compact`) that runs `hippo compact-resume` after a compaction, so the next prompt sends that block again. Codex gets no `PreCompact` hook from hippo, so it restores a task snapshot only if one was saved with `hippo snapshot save` in the last 15 minutes
|
|
799
799
|
|
|
800
800
|
**Codex runs a new or changed hook only after you trust it, so open `/hooks` in Codex once and trust both;** `hippo doctor` reminds you. The per-prompt hook was checked against a real Codex request; the compaction hook follows Codex's documented `compact` start source and has not been watched end to end in Codex. Each hook also carries a `commandWindows` form (`hippo.cmd ...`), because Codex runs hooks through PowerShell on Windows, where the execution policy can block npm's `hippo.ps1`. hippo only ever appends these two entries and never rewrites one, since Codex treats a changed command as a new hook to trust. To remove: `hippo hook uninstall codex`, which takes out only hippo's exact commands and leaves every other hook, including one of yours that runs hippo.
|
|
@@ -1056,7 +1056,7 @@ node run.mjs --adapter all
|
|
|
1056
1056
|
|
|
1057
1057
|
### How do I give Claude Code memory between sessions?
|
|
1058
1058
|
|
|
1059
|
-
Run `npm install -g hippo-memory`, then `hippo init` in the project. 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 7 hook entries to Claude Code's settings that keep your pinned memories plus
|
|
1059
|
+
Run `npm install -g hippo-memory`, then `hippo init` in the project. 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 7 hook entries to Claude Code's settings that keep your pinned memories plus up to 5 that match the prompt in context, save a task snapshot and the memories a compaction summary lists, store failed tool calls as lessons, and run `hippo sleep` when the session ends, and it sets up a daily 6:15am run. [What hippo init changes](#what-hippo-init-changes) lists everything. 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. To set up every git repo up to three folders below your home directory at once, know what the scan changes first: each repo gets its own store, seeded from a year of its git history, the same hooks go in when one of those repos uses Claude Code, and the daily run is set up, but no block goes into any repo's `CLAUDE.md`. The command is `hippo init --scan ~`; run `hippo init` in the projects where you want the block.
|
|
1060
1060
|
|
|
1061
1061
|
### How do I give Cursor memory between sessions?
|
|
1062
1062
|
|
|
@@ -1064,7 +1064,7 @@ Run `npm install -g hippo-memory`, then `hippo init` in the project. If the proj
|
|
|
1064
1064
|
|
|
1065
1065
|
### How do I give Codex memory across sessions?
|
|
1066
1066
|
|
|
1067
|
-
`hippo init` adds its instructions to your `AGENTS.md`, which Codex reads before it starts work. When Codex is installed, init also adds two hooks to Codex's `hooks.json`: one puts your pinned memories plus
|
|
1067
|
+
`hippo init` adds its instructions to your `AGENTS.md`, which Codex reads before it starts work. When Codex is installed, init also adds two hooks to Codex's `hooks.json`: one puts your pinned memories plus up to 5 that match the prompt into every prompt, the other makes the next prompt send them again after a compaction. Codex asks you to trust each new hook once in `/hooks`, and skips it until you do. Capturing Codex sessions is opt-in: `hippo hook install codex` wraps the Codex launcher, and `hippo hook uninstall codex` removes the wrapper and the hooks.
|
|
1068
1068
|
|
|
1069
1069
|
### Which agents does hippo work with?
|
|
1070
1070
|
|
package/dist/cli.js
CHANGED
|
@@ -8773,7 +8773,7 @@ Commands:
|
|
|
8773
8773
|
--budget <n> Token budget for the whole printed block (default: 1500)
|
|
8774
8774
|
--pinned-only Only inject pinned memories (used by UserPromptSubmit hook)
|
|
8775
8775
|
--include-recent <n> With --pinned-only, also inject the last N writes regardless of pinning
|
|
8776
|
-
(the hook payload's "prompt" drives prompt recall instead of --include-recent when pinnedInject.promptRecall is on)
|
|
8776
|
+
(the hook payload's "prompt" drives prompt recall instead of --include-recent when pinnedInject.promptRecall is on, the default)
|
|
8777
8777
|
--format <fmt> Output format: markdown (default), json, or additional-context (Claude Code hook JSON)
|
|
8778
8778
|
--framing <mode> Framing: observe (default), suggest, assert
|
|
8779
8779
|
sleep Run consolidation pass (auto-learns + dedup + auto-shares)
|
package/dist/config.d.ts
CHANGED
|
@@ -71,8 +71,8 @@ export interface HippoConfig {
|
|
|
71
71
|
* never resends an unchanged block. */
|
|
72
72
|
refreshTurns: number;
|
|
73
73
|
/** Z1: gate the hook's backfill on the prompt's own content instead of
|
|
74
|
-
* the five newest memories. Default
|
|
75
|
-
* (docs/evals/2026-09-26-z1-prompt-recall-result.md). */
|
|
74
|
+
* the five newest memories. Default true since 1.55.0: overlap tied but median
|
|
75
|
+
* tokens fell 847 to 533 (docs/evals/2026-09-26-z1-prompt-recall-result.md). */
|
|
76
76
|
promptRecall: boolean;
|
|
77
77
|
/** Z1: overlap metric for the prompt-recall gate. Default 'jaccard' (tuned, docs/evals/2026-09-26-z1-prompt-recall-result.md). */
|
|
78
78
|
promptRecallMetric: PromptRecallMetric;
|
package/dist/config.js
CHANGED
package/dist/hooks.d.ts
CHANGED
|
@@ -156,7 +156,7 @@ export declare function codexHomeDir(home?: string, env?: Readonly<Record<string
|
|
|
156
156
|
/** Codex counts as installed only when its config folder exists: Codex itself refuses a CODEX_HOME that is not a folder. */
|
|
157
157
|
export declare function isCodexPresent(home?: string): boolean;
|
|
158
158
|
/** Codex hashes each hook and skips new or changed ones until the user reviews them in `/hooks`, so the reminder says what they would trust. */
|
|
159
|
-
export declare const CODEX_TRUST_LINE = "The per-prompt hook sends your pinned memories plus
|
|
159
|
+
export declare const CODEX_TRUST_LINE = "The per-prompt hook sends your pinned memories plus up to 5 that match the prompt. Codex runs hippo's hooks only after you trust them once in `/hooks`.";
|
|
160
160
|
/**
|
|
161
161
|
* Default log path consumed by `hippo last-sleep`. Shared fallback when
|
|
162
162
|
* a caller doesn't pass --path explicitly.
|
package/dist/hooks.js
CHANGED
|
@@ -134,7 +134,7 @@ export function isCodexPresent(home = homeDir()) {
|
|
|
134
134
|
return fs.statSync(codexHomeDir(home), { throwIfNoEntry: false })?.isDirectory() === true;
|
|
135
135
|
}
|
|
136
136
|
/** Codex hashes each hook and skips new or changed ones until the user reviews them in `/hooks`, so the reminder says what they would trust. */
|
|
137
|
-
export const CODEX_TRUST_LINE = "The per-prompt hook sends your pinned memories plus
|
|
137
|
+
export const CODEX_TRUST_LINE = "The per-prompt hook sends your pinned memories plus up to 5 that match the prompt. Codex runs hippo's hooks only after you trust them once in `/hooks`.";
|
|
138
138
|
/**
|
|
139
139
|
* Default log path consumed by `hippo last-sleep`. Shared fallback when
|
|
140
140
|
* a caller doesn't pass --path explicitly.
|
package/dist/session-digest.js
CHANGED
|
@@ -23,8 +23,6 @@ export const MAX_FILES = 10;
|
|
|
23
23
|
export const MAX_DIGEST_CHARS = 1200;
|
|
24
24
|
/** Bounds a detached worker's memory; the final message sits at the end, so a tail read loses nothing. */
|
|
25
25
|
export const READ_CAP_BYTES = 64 * 1024 * 1024;
|
|
26
|
-
/** The pinned hook shows the newest 5 memories, so older digests were never injected. */
|
|
27
|
-
const RECENT_DIGESTS = 5;
|
|
28
26
|
const CLAUDE_EDIT_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);
|
|
29
27
|
function transcriptItem(value) {
|
|
30
28
|
return isObjectLike(value) && 'type' in value ? value : null;
|
|
@@ -441,12 +439,10 @@ export function isSessionDigestRow(entry) {
|
|
|
441
439
|
export function sessionDigestId(tenantId, key) {
|
|
442
440
|
return `mem_${createHash('sha256').update(`${SESSION_DIGEST_TAG}\n${tenantId}\n${key}`).digest('hex').slice(0, 12)}`;
|
|
443
441
|
}
|
|
444
|
-
/** What hippo could have injected into the session:
|
|
442
|
+
/** What hippo could have injected into the session: any live digest (prompt recall reaches old ones) and the ambient handoff, never this session's own. */
|
|
445
443
|
function injectedTexts(hippoRoot, opts) {
|
|
446
444
|
const digests = loadAllEntries(hippoRoot, opts.tenantId)
|
|
447
445
|
.filter((e) => isSessionDigestRow(e) && !e.superseded_by && e.source_session_id !== opts.key)
|
|
448
|
-
.sort((a, b) => (a.created < b.created ? 1 : a.created > b.created ? -1 : 0))
|
|
449
|
-
.slice(0, RECENT_DIGESTS)
|
|
450
446
|
.map((e) => e.content);
|
|
451
447
|
const handoff = loadLatestHandoff(hippoRoot, opts.tenantId, undefined, {
|
|
452
448
|
unfinishedOnly: true,
|
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.
|
|
19
|
+
export declare const PACKAGE_VERSION = "1.55.0";
|
|
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.
|
|
19
|
+
export const PACKAGE_VERSION = '1.55.0';
|
|
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) => {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "hippo-memory",
|
|
3
3
|
"name": "Hippo Memory",
|
|
4
4
|
"description": "Memory for AI agents that learns what is wrong and ranks it down. Injects context at session start and captures errors.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.55.0",
|
|
6
6
|
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "hippo-memory",
|
|
3
3
|
"name": "Hippo Memory",
|
|
4
4
|
"description": "Memory for AI agents that learns what is wrong and ranks it down. Injects context at session start and captures errors.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.55.0",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hippo-memory",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.55.0",
|
|
4
4
|
"description": "Memory for AI agents that learns what is wrong and ranks it down. MCP server, hooks for Claude Code, OpenCode and Codex, AGENTS.md instructions for Codex, Cursor, OpenClaw and Pi. SQLite, zero runtime deps.",
|
|
5
5
|
"mcpName": "io.github.kitfunso/hippo-memory",
|
|
6
6
|
"type": "module",
|