mw retention report is a read-only inventory of the local MemoryWhale store.
It reports session and command counts, retained byte totals, oldest/newest
timestamps, largest command outputs, pending agent notes, and project/agent
breakdowns. It also names the evidence a future purge could target. The
command is always a dry run and does not delete database rows or transcript
files; any future purge must use narrow selectors and explicit confirmation.
Cursor capture is a separate opt-in mode:
mw integrate cursor --capture [--hooks-file <file>] [--dry-run|--check|--revert].
The helper accepts mw-remember --from-hook cursor. See the
Cursor guide for documented payload
coverage, unknown exit handling, and the pending live-client verification.
Codewhale capture uses a separate, optional native Codewhale capture plugin
which submits receipts to mw-remember --from-hook codewhale and requires a
Codewhale host build supporting execution receipts. The base
Codewhale MCP plugin remains hook-free; MCP access alone does not enable
capture. There is no mw integrate codewhale --capture installer command.
The development branch adds mw integrate codex|cursor with --dry-run,
--check, --revert, and optional --config <file> for owned MCP setup.
These are configuration checks, not proof of a running client connection.
mw integrate rho|codex|cursor --skill <local SKILL.md> installs only an
explicitly supplied local instruction skill. Supports --dry-run, --check,
--revert, and --skills-dir <directory>. See
portable integrations for the separate Rho memory
setup, safe removal rules, discovery paths, and live Rho verification.
These additions ship in 0.11.0.
Released commands ship as prebuilt binaries (see the README's Install section). If
you're working from a source checkout instead, prefix any command with
cargo run -p memorywhale-cli --bin <name> -- from the repo root, e.g.
cargo run -p memorywhale-cli --bin mw -- --notes "…".
mw --notes "Jetson build debugging" # record a whole shell session until exit
mw --live --notes "project:demo" # autosave to SQLite every few seconds
mw --version # print the installed MemoryWhale version
mw list # list recorded sessions
mw timeline --project demo # read-only chronological project events
mw timeline --project demo --after 2026-01-01 --before 2026-02-01 --type command --limit 50
mw show 1 # print the full transcript of a session
mw search "linker error" # search commands, output, notes, transcripts
mw search docker after:2026-01-01 tag:infra # filter results: tag:X, source:command|session|note|document|conversation, agent:claude|rho|cursor|codewhale|codex|gemini|terminal, before:/after:YYYY-MM-DD, limit:N
mw search "build" --mode lessons # explicit view: evidence, lessons, recipes, or failures
mw search "flaky test" --use-feedback # reorder by recorded feedback (opt-in; see below)
# evidence = everything except saved notes; lessons = saved notes (mw remember and mw mark share storage); recipes = notes with a fix: marker
mw explain 1000000001 # why this memory ranks: per-signal breakdown (ids come from `mw search`)
mw link 1000000001 3000000001 rel:fixed-by # link two memories (typed edge; ids from `mw search`)
mw links 1000000001 # show a memory's linked neighbors (both directions); mw unlink <a> <b> removes
mw contradictions 1000000001 1000000002 # heuristic contradiction check; stores a pending flag (see docs/contradiction-flags.md)
mw contradictions list # review flags: then mw contradictions confirm|reject <flag-id>
mw tui # interactive terminal browser (type to search, Enter to act, F1 help, Esc quit)
mw git-fix # diagnose the last failed git command: what, why, the fix
mw github context <pr> # fetch bounded, redacted GitHub PR context through gh
mw mark "before the risky flash" # bookmark the current debugging moment
mw remember "the fix was passing --features vendored-ssl" # save a lesson/conclusion (warns on a near-duplicate; add --force to save anyway)
mw remember "staging creds rotate friday" ttl:7d # auto-expires after 7d (m/h/d/w) — drops from retrieval, evidence preserved
mw replay 12 # rerun a saved command run
mw compare 12 34 # compare two saved command runs, including provenance and differences
mw demo # seed a small demo dataset to explore
mw rm 5 # delete a session (+ its transcript); mw rm command <id> for a run
mw prune [--min-bytes N] [--dry-run] # delete empty auto-recorded sessions (noise cleanup)
mw memory stale <id> # retire an outdated lesson, preserving its row
mw memory supersede <old> <new> # replace an old lesson with a newer one
mw memory compact [--apply] # preview/apply conservative evidence compaction
mw audit # inspect capture policy and retained volume
mw integrate claude [--revert] # install or remove Claude Code hook, skill, and MCP server
mw integrate rho [--revert] [--http [url]] [--token secret] # Rho hook, skill, and MCP (stdio default; --http for mw-serve POST /mcp)
mw integrate hermes # register mw-mcp in Hermes Agent's config
mw integrate delphin # check Delphin, print `delphin --memorywhale -- claude`
mw share 5 [-o file.html] # write a self-contained HTML page of one item to send someone
mw discard # inside a recording: throw the current session away
mw context [project:name] [--last-error] [--limit N] # compact failures digest for agents
mw hint <error line> # one line: seen before? what fixed it (Delphin live hints)
mw turns --session ID [--cwd DIR] # record JSON-line conversation turns from stdin (Delphin)
mw agent [session-id] # export a full session as text to paste into an agent
mw ask [question] [--chat gemini] # package the last failure for your chat AI → clipboard
mw pet [--watch] # show the whale whose mood reflects the memory store
mw doctor # check the install, shell hooks, MCP server, and Claude/Rho integrations
mw export [project:name] # export a bundle (Markdown + JSON + SQLite)
mw import <bundle|sqlite> # merge another machine's export
mw push <ssh-host> # send this machine's memory to another (scp + remote import)
mw pull <ssh-host> [path] # the reverse: copy another machine's memory here and merge it
mw global on|off|status # auto-record every new terminalimport, push, and pull carry retrieval feedback and typed mw link edges
across machines. As they merge the memory tables they build an old-to-new
row-id map and remap each feedback record and link to the destination IDs, so
recall on the other machine keeps its feedback and relationships. A record whose
target memory did not import is skipped and counted, and re-import is idempotent.
Recipes are local metadata assembled only from explicitly selected recorded
command IDs. Saving records the description, cwd, arguments, expected criteria,
and source-run links; it never executes a command. The description,
criteria, and cwd are redacted before they are stored, like other captured
text. copy only prints the recorded argument JSON (redacted) and is safe to
inspect; it is not guaranteed to be a pasteable shell command.
These saved recipes are separate from mw search --mode recipes, which
selects notes that carry a fix: marker.
Every --run must share the same command and arguments (duplicates are
ignored); the first listed run supplies the default cwd, and show lists
sources in the order given. A recipe keeps its own payload, so mw rm command
or mw prune --older-than on a source run only drops that provenance link.
Recipes are not carried by mw import, push, or pull.
mw recipe save --run 12,19 --description "rebuild" --cwd /work --criteria "tests pass"
mw recipe list
mw recipe show 1
mw recipe copy 1
mw starts a recorded subshell; run commands normally, then exit or Ctrl-D
to stop. The raw transcript lands in the data folder, searchable metadata in
SQLite. --live matters for SSH sessions and sudden shutdown risk: if the
terminal dies before exit, the last autosaved transcript is still there.
Recorded a garbage terminal? Type mw discard inside it before exiting, or
mw rm <id> after the fact.
Memories written through MCP start pending by default and stay out of retrieval
until approved in the TUI review pane. To opt into automatic approval, set
MEMORYWHALE_REVIEW_AGENT_MEMORIES=0 or add
review_agent_memories = false to config.toml.
Use mw memory stale <id> when advice is no longer current, or
mw memory supersede <old-id> <new-id> when a newer lesson replaces it. Both
commands preserve the original rows and provenance while excluding retired
memories from normal retrieval.
See the memory compaction reference for the dry-run-first
policy, protected evidence rules, thresholds, and --apply behavior.
mw context gives an agent a short digest of recent failures; mw agent
dumps a whole session transcript as Markdown to hand over later — e.g.
mw agent > session.md or mw agent | pbcopy. mw remember/mw mark share
one store (a "note") — once you've figured out why something failed or how
a fix worked, mw remember saves that conclusion so mw search/mw context
surface it later instead of re-deriving it. For live agent access, register the
MCP server instead (see mw-mcp below — it also exposes a remember tool, so
the agent can write lessons itself).
mw ask is the bring-your-own-AI bridge: it packages the most recent failure
(exact error, cwd, exit code) plus similar past failures and saved lessons into
one debugging prompt, copies it to the clipboard, and opens chatgpt.com — you
paste (Cmd-V) and the chat has full context. No API key, and no per-token
billing: it rides the flat-rate chat subscription you already pay for
(ChatGPT/Claude/Gemini — effectively unlimited for daily debugging, where
API-key tools meter every call). The payload is plain Markdown. Pick the chat
with --chat chatgpt|claude|gemini (or any URL), or set a permanent default
with MEMORYWHALE_CHAT=gemini in your shell rc. Add a question
(mw ask "why does this keep breaking"), include the tail of the current
session with --session, or skip the browser with --no-open. Everything in
the payload was secret-redacted at capture time.
mw doctor also probes the local mw-mcp executable with a bounded,
read-only MCP handshake and tools/list request. It reports whether the
binary is missing, timed out, returned an invalid response, or advertised the
expected six tools. It never calls a memory tool or edits a client
configuration.
After those install checks, mw doctor prints an Integrations section for
Claude Code and Rho. MCP registration, the auto-capture hook, and the bundled
skill are reported independently. Missing optional pieces tell you to run
mw integrate <client>. Absent client configs or CLIs are not detected,
not a failed MemoryWhale install. CLAUDE_CONFIG_DIR and RHO_HOME are
honored. Doctor does not run client CLIs or print tokens.
mw github context <pr> explicitly fetches PR metadata, check runs, classic
commit statuses, and reviews using your existing gh authentication. It prints
bounded, redacted context without saving it. Linux, macOS, and WSL are supported;
native Windows is rejected before spawning gh because this release does not
provide deadline-safe native Windows subprocess capture.
mw git-fix recognizes a handful of common git failure shapes — push rejected
(non-fast-forward), merge conflicts, a dirty working tree blocking an
operation, diverged branches, unrelated histories, and SSH auth failures — from
the stderr already captured in command_runs. It explains what happened,
prints the fix, and checks whether this exact class of failure has come up
before (a past command run, or a lesson you already mw remember'd). With no
argument it uses the most recent failed git command; mw git-fix <id>
targets a specific command_run id (from mw list/mw search). Patterns it
doesn't recognize get an honest "didn't recognize this" instead of a wrong
guess.
mw-run --notes "Check the Rust backend" -- cargo checkOutput still streams to your terminal while a copy (stdout, stderr, exit code,
cwd, argv) is saved. mw-run exits with the same exit code as the command.
mw handoff --ids c:ID,s:ID [--format markdown|json] --output FILE writes an explicit, local-only handoff. It refuses existing output files, redacts bounded evidence, and performs no network operation.
mw-remember \
--cwd . \
--exit-code 127 \
--stderr "zsh:1: command not found: cargo" \
--notes "Rust verification failed because cargo was missing" \
-- cargo check --manifest-path src-tauri/Cargo.tomlAgent capture hooks spawn mw-remember --from-hook claude or
mw-remember --from-hook rho with that client's hook JSON on stdin. No
Python runtime is required.
mw-screenshot --notes "VS Code showed the TypeScript warning"Local-only and opt-in. On headless machines (e.g. a Jetson without a display) screenshot capture may fail; terminal memory recording still works.
mw sync-mempalace [--wing NAME] [--limit N] [--dry-run]Pushes local memories into a running MemPalace
server (needs mempalace_command in config.toml). The sync is idempotent by
memory id: a local mempalace_sync table maps each memory to the drawer it
became. On each run:
- a new memory is added as a drawer, and the mapping recorded;
- an edited memory (its drawer content changed) has its old drawer deleted and a fresh one added — so exactly one up-to-date drawer survives;
- an unchanged memory is skipped (no server call).
Provenance rides along: each drawer's content is prefixed with a stable
[memorywhale <source> #<id>] tag, notes also carry their "remembered by … on …"
line, and added_by is set to the author. --dry-run prints the planned
add/update/skip breakdown without contacting the server.
mw-serve [--lan | --host addr] [--port n] [--token secret] [--print-token] [--api] # dashboard, HTTP MCP, optional JSON API
mw-view <id> # open one memory directly
mw-recover # recover interrupted recordings
mw-mcp # MCP server for AI agents (stdio): recent_errors, search_memory, get_context, remember, similar_failures, stats — see docs/reference/mcp.mdThe opt-in /api/v1 JSON API is enabled with mw-serve --api. See the
local JSON API reference for its read-only endpoints and response
envelopes.
By default the SQLite database lives in the local app data directory. Set
MEMORYWHALE_DATA_DIR for an explicit location:
MEMORYWHALE_DATA_DIR=/tmp/memorywhale-data mw-run -- echo "saved here"Captured stdout/stderr/notes/transcripts are scrubbed for common secret shapes
(API keys, tokens, password=, PEM blocks) before they reach SQLite. Set
MEMORYWHALE_NO_REDACT=1 to store raw text.
Captured text fields are limited to 1 MiB by default. Set
MEMORYWHALE_MAX_CAPTURE_BYTES to a positive byte count to tune the limit;
truncated values include a marker with the stored and original byte counts.
See the local data threat model before enabling raw capture or
sharing exported data.
mw doctor capture runs an explicit, isolated capture health probe. It reports
configuration and hook wiring read-only, then writes one synthetic record only
to a temporary SQLite store that is removed before exit. It distinguishes the
isolated store, synthetic receipt acknowledgement, last isolated record, and
fresh end-to-end capture result. It does not inspect or modify the normal store,
enable hooks, or change configuration.
mw search keeps its existing weighted-mean ranking by default. To opt in to a
transparent evidence ranking, pass --ranking bayesian (or
ranking:bayesian). The returned score is a posterior_proxy: a neutral-prior,
weighted log-odds-style combination of the existing similarity, recency,
importance, reinforcement, and task signals. It is not a calibrated
probability. With --explain, each signal's line shows its log-odds term
weight × logit(score) (score clamped to [0.01, 0.99]); the terms sum to the
total inside sigmoid(...). Explanations continue to show every signal,
including pending, contradicted, or stale evidence; this ranking is
retrieval-only and must not be used for authorization. --ranking requires a
value (default or bayesian); anything else is a usage error. An explicit
--ranking always uses the builtin engine, even when MemPalace is configured.
MCP search_memory accepts "ranking":"default" or "ranking":"bayesian";
other values are rejected, and omitting it preserves the existing output and
ordering.
mw search ignores recorded retrieval feedback by default. Pass --use-feedback
to reorder the retrieved results by the feedback stored with mw feedback add.
It is opt-in and reorders only: without the flag the ranking and output are
unchanged, and even with it the relevance score shown for each hit (and its
--explain breakdown) is untouched — feedback breaks near-ties and lifts or
sinks a memory a rung, it does not rewrite relevance.
Only active feedback counts (rows not undone with mw feedback undo). Per
memory, feedback nets to helpful minus irrelevant/outdated/contradicted;
that net is turned into a bounded ranking nudge of net × 0.05, clamped to
±0.15, added to the score purely for ordering. So one net helpful lifts a
memory by 0.05, three or more by the 0.15 cap; a clear relevance gap always
wins. The sort is stable: ties and memories with no feedback keep their prior
order, and nothing is ever filtered out. With --explain, each hit gains a
feedback: line naming its net and the applied nudge.
Feedback is stored locally and keyed to local memory ids, so --use-feedback
always uses the builtin engine (it skips MemPalace, like --ranking). It
reorders already-retrieved, already-approved, in-scope results only; it never
resurfaces unapproved or out-of-scope memories.
MCP search_memory accepts "use_feedback": true for the same behaviour;
omitting it (or false) preserves the existing output and ordering.