Skip to content

Latest commit

 

History

History
364 lines (253 loc) · 14.8 KB

File metadata and controls

364 lines (253 loc) · 14.8 KB

me memory

Manage memories.

Memories are the core data type in Memory Engine. Each memory has content, an optional tree path for hierarchical organization, an optional filename-like name (unique within the tree), optional metadata, and an optional temporal range.

Commands


me memory create

Create a memory.

me memory create [content] [options]
Argument Required Description
content no Memory content. Can also be provided via --content or stdin.
Option Description
--content <text> Memory content (alternative to positional argument).
--tree <path> Required. Tree path where the memory is stored (e.g., /share/work/projects). Use /share for memories the rest of the space should see, or ~ (your private home, e.g. ~/notes) for memories that must stay private to you.
--name <slug> Optional filename-like leaf name, unique within the tree (e.g. jwt-rotation). Lets you later address the memory by path (/share/auth/jwt-rotation) and re-create idempotently.
--meta <json> Metadata as a JSON string.
--temporal <range> Temporal range as start[,end] (ISO 8601).
--replace On a conflict (a --name already taken in that tree), replace the existing memory in place when content/meta/temporal differ -- a no-op when identical.
--ignore On a conflict, skip silently and leave the existing memory untouched.

Content can come from the positional argument, the --content flag, or piped via stdin. A --tree path is required. Without --replace/--ignore, creating a second memory with a --name already used in that tree errors with CONFLICT.


me memory get

Get a memory by ID or by its tree/name path. In a TTY, renders the content as ANSI-formatted markdown with dimmed YAML frontmatter. When piped or redirected, outputs raw Markdown with YAML frontmatter (suitable for > file.md).

me memory get <id-or-path> [options]
Argument Required Description
id-or-path yes A memory ID (UUIDv7), or a named memory's tree/name path (e.g. /share/auth/jwt-rotation, ~/notes/todo). A UUID is fetched by id; anything else is resolved by path (split at the final /).
Option Description
--raw Output raw Markdown with YAML frontmatter (no ANSI), even in a TTY.
me memory get 0194a000-0001-7000-8000-000000000001   # by id
me memory get /share/auth/jwt-rotation                # by path

me memory search

Search memories.

me memory search [query] [options]
Argument Required Description
query no Hybrid search query (uses both semantic and fulltext search).
Option Description
--semantic <text> Semantic (vector) search query.
--fulltext <text> BM25 keyword search.
--grep <pattern> Regex filter on content (POSIX, case-insensitive).
--tree <filter> Tree path filter. Supports exact match, wildcards, negation, and label search. See Tree filter syntax.
--meta <json> Metadata filter as JSON.
--limit <n> Max results (default: 10).
--candidate-limit <n> Pre-RRF candidate pool size.
--semantic-threshold <n> Minimum semantic similarity score, 0-1.
--temporal-contains <ts> Memory must contain this point in time.
--temporal-overlaps <range> Memory must overlap this range (start,end).
--temporal-within <range> Memory must be within this range (start,end).
--weight-semantic <w> Semantic weight, 0-1.
--weight-fulltext <w> Fulltext weight, 0-1.
--order-by <dir> Sort direction: asc or desc.

At least one search criterion is required. A positional query runs hybrid search by sending the same text to semantic and fulltext ranking. Use --semantic for pure vector search, --fulltext for pure keyword search, or both flags to provide different text for each mode.

Examples

# Hybrid search
me memory search "how does authentication work"

# Keyword search
me memory search --fulltext "pgvector ltree"

# Hybrid with tree filter
me memory search --semantic "embedding performance" --fulltext "nomic" --tree "/share/design/*"

# Browse by metadata
me memory search --meta '{"type": "decision"}' --limit 20

me memory update

Update a memory.

me memory update <id-or-path> --version-hash <hash> [options]
Argument Required Description
id-or-path yes A memory ID (UUIDv7), or a memory's tree/name path (e.g. /share/auth/jwt-rotation).
Option Description
--version-hash <hash> Required. The current versionHash of the memory (32-char md5 hex). Get it from a recent me memory get/search/create/update response. The server rejects the update with CONFLICT if the hash is stale (another writer changed the memory in the meantime), leaving the memory unchanged.
--content <text> New content (use - for stdin).
--tree <path> New tree path.
--name <slug> Set or rename the memory's name. Pass an empty string (--name "") to clear it.
--meta <json> New metadata as JSON (replaces existing).
--temporal <range> New temporal range as start[,end].

At least one update field is required. Metadata is fully replaced, not merged. Update is id-addressed; you can pass a tree/name path as the <id-or-path> argument and the CLI resolves it to an id first. me memory edit handles --version-hash automatically — it fetches the memory before opening the editor and submits the captured hash on save.


me memory delete

Delete a single memory, by ID or by its tree/name path. To delete a whole subtree, use me memory deltree.

me memory delete <id-or-path>
Argument Required Description
id-or-path yes A memory ID (UUIDv7), or a memory's tree/name path (e.g. /share/auth/jwt-rotation).

A UUIDv7 deletes that one memory by id; anything else is a tree/name path (split at the final /) that deletes at most that one named memory. It never deletes a subtree — a path that names no existing memory reports "not found" rather than removing everything beneath it.

Alias: me memory rm.


me memory deltree

Delete every memory at or under a tree path (a subtree).

me memory deltree <tree> [options]
Argument Required Description
tree yes A tree path; all memories at or under it are deleted (e.g. /share/old-project).
Option Description
--dry-run Preview the count without deleting anything.
-y, --yes Skip the confirmation prompt.

Always previews the count first, so --dry-run can never delete. Without --yes, an interactive run shows the count and asks to confirm before deleting.

Alias: me memory rmtree.


me memory edit

Open a memory in your editor.

me memory edit <id>
Argument Required Description
id yes Memory ID (UUIDv7).

Fetches the memory, formats it as Markdown with YAML frontmatter, and opens it in $VISUAL, $EDITOR, or vim. On save, the CLI parses your changes and sends an update. The fetched memory's versionHash is submitted automatically, so concurrent edits by another writer surface as a CONFLICT (rerun me memory edit to pull the latest state). If there are errors, the editor re-opens.


me memory count

Count memories matching a tree filter. Alias: me count.

me memory count <tree> [options]
Argument Required Description
tree yes Tree filter: an exact path prefix, a wildcard pattern, or a label search (see Tree filter syntax).
Option Description
--max-count <n> Stop counting after this many matches. If the returned count reaches this value, text output says at least N memories.

Examples:

me memory count share.projects
me memory count 'share.projects.*' --max-count 100
me memory count 'api & v2'

me memory tree

Show memory tree structure.

me memory tree [filter] [options]
Argument Required Description
filter no Root tree path to start from.
Option Description
--levels <n> Max depth to display.

Renders the tree with box-drawing characters, showing memory counts at each node.


me memory copy

Copy memories between tree paths. Alias: me memory cp.

me memory copy <src> <dst> [options]
Argument Required Description
src yes Source tree path.
dst yes Destination tree path.
Option Description
--dry-run Preview what would be copied without executing.
-y, --yes Skip the confirmation prompt.

Copies all memories under the source prefix to the destination, preserving subtree structure. The source memories are preserved and copied memories receive new IDs. Repeating a real copy creates additional copies. Always shows a preview count before confirming.

Examples:

me memory copy share.old share.archive --dry-run
me memory copy share.old share.archive --yes

me memory move

Move memories between tree paths. Alias: me memory mv.

me memory move <src> <dst> [options]
Argument Required Description
src yes Source tree path.
dst yes Destination tree path.
Option Description
--dry-run Preview what would be moved without executing.
-y, --yes Skip the confirmation prompt.

Moves all memories under the source prefix to the destination, preserving subtree structure. Always shows a preview count before confirming.


me memory import

Import memories from files or stdin. This is an alias of me import memories (unlike the other memory subcommands, import has no bare top-level alias — the top-level me import is the import group).

me memory import [files...] [options]
Argument Required Description
files... no Files to import (use - for stdin).
Option Description
--format <format> Override format detection (md, yaml, json).
-r, --recursive Recursively import from directories.
--fail-fast Stop on first error.
--dry-run Validate without importing.
-v, --verbose Show per-file status output.

Supports Markdown (with YAML frontmatter), YAML, JSON, and NDJSON. Format is auto-detected from file extension or content. See File Formats for full schema documentation.

Skipped memories

Import submits with onConflict: 'ignore', so a record whose idempotency key already exists -- a named record's (tree, name) slot (name takes precedence), else its explicit id -- is silently skipped rather than failing the whole batch. The command surfaces these as skipped so re-imports of unchanged data and id collisions with unrelated memories are observable. Records without an id and without a name get a server-generated UUIDv7 and never collide.

JSON output adds skipped (count) and skippedIds (array of the skipped rows' stored ids). Text output appends (K skipped — already exist) to the summary, or prints Imported 0 memories (N already exist, no changes) when everything was a re-import. Run with --verbose to see each skipped id inline. The server reports a per-row status, so a named, id-less record skipped on its (tree, name) slot is counted too.

Skipped memories do not contribute to the exit code; only parse and server errors do.

--dry-run validates parsing only; it does not predict id collisions with already-imported memories. Run with --verbose after a real import to see the skipped ids.

Chunking and partial failures

Large imports are sliced into multiple batchCreate requests under the hood to fit under the server's request-body limit. Each chunk is sent sequentially. If a chunk fails (network error, server error), siblings are not affected -- the successful chunks still land. The failed chunk's items are reported as failed, and the chunk-level error message appears in the errors array (sourced as chunk N (K items)).

This means partial failures are possible: imported > 0 and failed > 0 can both be true in the same run. Re-running the import with the same input will pick up where the previous run left off (already-present rows are skipped via onConflict: 'ignore', missing ones are inserted).


me memory export

Export memories with filters.

me memory export [file] [options]
Argument Required Description
file no Output file or directory (stdout if omitted).
Option Description
--tree <filter> Tree path filter.
--format <fmt> Output format: json, yaml, md (default: json).
--meta <json> Metadata filter as JSON.
--limit <n> Max memories to export (default: 1000).
--temporal-contains <ts> Memory must contain this point in time.
--temporal-overlaps <range> Memory must overlap this range.
--temporal-within <range> Memory must be within this range.

For md format with a directory output, the directory mirrors the tree: each memory is written to <dir>/<tree-as-directories>/<name-or-id>.md. A named memory uses its name as the filename; an unnamed one falls back to {id}.md. Frontmatter includes name when set. Exported content is compatible with me memory import. See File Formats for full schema documentation.