Skip to content

Latest commit

 

History

History
344 lines (283 loc) · 19.2 KB

cli.md

File metadata and controls

344 lines (283 loc) · 19.2 KB

Privacy retention report

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.

CLI reference

Portable client setup and optional skills

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 — record sessions

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 terminal

import, 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.

Reusable command recipes

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 — capture one command

mw-run --notes "Check the Rust backend" -- cargo check

Output 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 — export selected debugging evidence

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 — save output you already have

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.toml

Agent 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 — opt-in visual evidence

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 — mirror memories into MemPalace

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 / mw-view / mw-recover / mw-mcp

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.md

The 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.

Data location

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"

Secret redaction

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.

Capture doctor

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.

Optional Bayesian-style ranking

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.

Optional feedback-adjusted ranking

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.