Unified coding-agent session memory for Pi, Factory Droid, OpenCode, Claude Code, Amp, and Codex.
Tired of hunting through multiple agent transcript formats and folders? Remi gives you one searchable memory layer.
Remi ingests local agent transcripts into one SQLite database, keeps sync state with checkpoints, supports ranked search, and provides safe archive/restore workflows.
Current support status: Linux-first (default source discovery paths are validated on Linux).
- What Remi does
- Demo
- Quickstart
- Install / build
- Data locations
- Supported agent sources
- CLI reference
- Semantic search (optional feature)
- End-to-end workflow examples
- Helper scripts (examples)
- Architecture at a glance
- Release artifacts
- Homebrew (optional)
- License
- Incremental sync from multiple coding-agent sources.
- Deterministic IDs (
blake3) for idempotent upserts. - Checkpointed ingestion using a composite cursor (
timestamp + source_id) to avoid missing same-timestamp records. - Structured content normalization including tool-call/tool-result payloads into searchable text.
- Lexical search using SQLite FTS5 + BM25.
- Ranking fusion with recency via Reciprocal Rank Fusion (RRF).
- Substring fallback when lexical matches are empty.
- Two-layer search UX: ranked session list first, then export selected session to HTML/Markdown (or emit JSON).
- Archive planning/execution/restore with dry-run defaults and verification before optional deletion.
Full CLI demo (55s):
remi init && remi sync --agent all && remi search query "panic"If remi is not on your path yet, run from source:
cargo run -p cli -- init
cargo run -p cli -- sync --agent all
cargo run -p cli -- search query "panic"cargo install --path crates/clicargo install --git https://github.com/lsj5031/Remi --bin remicargo build --workspacecargo run -p cli -- --helpDefault paths on Linux (via dirs crate):
- Database:
~/.local/share/remi/remi.db - Search exports (HTML/Markdown default output):
~/.local/share/remi/exports/ - Archive bundles:
~/.local/share/remi/archive/<run_id>/
macOS and Windows builds are available in releases, but default agent source discovery paths are currently Linux-oriented.
Remi currently discovers and ingests from:
| Agent | Paths scanned |
|---|---|
| Pi | ~/.pi/agent/sessions/**/*.jsonl, ~/.pi/sessions/**/*.jsonl |
| Factory Droid | ~/.factory/sessions/**/*.jsonl, ~/.local/share/factory-droid/sessions/**/*.jsonl |
| OpenCode | ~/.local/share/opencode/opencode.db (preferred) or legacy ~/.local/share/opencode/storage/message/**/*.json (+ part text from ~/.local/share/opencode/storage/part/<message_id>/*.json; session metadata from ~/.local/share/opencode/storage/session/**/*.json) |
| Claude Code | ~/.claude/transcripts/**/*.jsonl, ~/.claude/projects/**/*.jsonl, ~/.local/share/claude-code/**/*.jsonl |
| Amp | ~/.local/share/amp/threads/**/*.json |
| Codex | ~/.codex/sessions/**/*.jsonl |
Top-level commands:
remi init
remi sync --agent <pi|droid|opencode|claude|amp|codex|all>
remi sessions <list|show>
remi search query <QUERY> [options]
remi archive <plan|run|restore>
remi doctor
If built with --features semantic, Remi also supports:
remi embed --rebuild- Global flags:
remi --ort-dylib-path <PATH> ...andremi --auto-ort ...
Initializes/open database schema (schema is also initialized automatically by other commands).
remi initSync a specific adapter or all adapters:
remi sync --agent pi
remi sync --agent droid
remi sync --agent opencode
remi sync --agent claude
remi sync --agent amp
remi sync --agent codex
remi sync --agent allBehavior:
- Discovers source files.
- Scans only records after the last checkpoint.
- Normalizes to canonical sessions/messages/provenance.
- Upserts into SQLite + refreshes FTS rows for touched sessions.
- Updates checkpoint cursor.
List sessions:
remi sessions listShow one session’s messages:
remi sessions show <session_id>Example:
remi sessions show 0d5f0e...c9aUsage:
remi search query [OPTIONS] <QUERY>Options:
--format <html|markdown|json>(default:html)--no-interactive--select <auto|index>(default:auto)--index <N>(required when--select indexin non-interactive mode)--agent <STRING>--title <STRING>--id <STRING>--contains <STRING>--raw-fts--html-safety <strict|relaxed|trusted>(default:relaxed)--output-dir <PATH>
remi search query "retry logic"Flow:
- Remi ranks matching sessions.
- You can type an optional fuzzy filter.
- You choose an index.
- Remi exports selected session (HTML by default) and prints the file path.
Interactive fuzzy filter supports field prefixes:
agent:claude title:auth contains:oauth refresh token
Supported fuzzy fields:
agent:title:id:contains:
Auto-select top result, export Markdown:
remi search query "panic on startup" \
--no-interactive \
--select auto \
--format markdownSelect exact ranked session index:
remi search query "sql migration" \
--no-interactive \
--select index \
--index 2 \
--format html \
--output-dir ./exportsEmit JSON instead of writing HTML/Markdown:
remi search query "cache invalidation" \
--no-interactive \
--select auto \
--format jsonFilter sessions before selection:
remi search query "build failure" \
--no-interactive \
--agent droid \
--title release \
--contains linkerremi archive plan --older-than 30d --keep-latest 5--older-thanuses human duration parsing (examples:30d,12h,90m)--keep-latestis applied per agent- Output format includes:
plan <run_id>
remi archive run --plan <run_id>Equivalent explicit dry-run:
remi archive run --plan <run_id> --dry-runremi archive run --plan <run_id> --executeThis writes:
~/.local/share/remi/archive/<run_id>/sessions.json~/.local/share/remi/archive/<run_id>/manifest.json
Remi verifies the bundle checksum after writing before allowing deletion.
remi archive run --plan <run_id> --execute --delete-sourceFlag precedence:
- Writes/deletes only occur when
--executeis set. - If both
--executeand--dry-runare passed,--dry-runwins and execution is suppressed.
remi archive restore --bundle ~/.local/share/remi/archive/<run_id>/sessions.jsonRun integrity checks and basic stats:
remi doctorCurrent output includes:
- SQLite
PRAGMA integrity_checkresult - total session count
Semantic support is feature-gated at compile time.
cargo build -p cli --features semanticWhen built with semantic, additional CLI surface is enabled:
- Global flags on
remi:--ort-dylib-path <PATH>--auto-ort
remi embed --rebuildremi search query ... --semantic <auto|on|off>
~/.config/remi/config.toml:
[semantic]
enabled = true
model_path = "/path/to/bge-small-en-v1.5"
pooling = "cls" # or "mean"
query_prefix = "Represent this sentence for searching relevant passages: "Model directory must contain:
model.onnxtokenizer.json
If model_path is not set, Remi checks:
<binary_dir>/models/bge-small-en-v1.5<binary_dir>/model~/.cache/remi/bge-small-en-v1.5
Rebuild embeddings:
remi embed --rebuildSearch with semantic mode:
remi search query "memoization strategy" --semantic auto
remi search query "memoization strategy" --semantic on
remi search query "memoization strategy" --semantic offSet ONNX Runtime path explicitly:
remi --ort-dylib-path /opt/onnx/libonnxruntime.so search query "vector index" --semantic onAuto-detect ONNX Runtime shared library:
remi --auto-ort search query "vector index" --semantic autoremi init
remi sync --agent all
remi sessions listThen inspect a session:
remi sessions show <session_id>remi search query "panic: index out of bounds" --format markdownOpen the emitted .md export path and review the full conversation.
remi search query "release tagging" --no-interactive --format json --select auto# plan
remi archive plan --older-than 60d --keep-latest 10
# inspect impact
remi archive run --plan <run_id>
# execute archive without deletion
remi archive run --plan <run_id> --execute
# optional deletion after validation
remi archive run --plan <run_id> --execute --delete-sourceRestore when needed:
remi archive restore --bundle ~/.local/share/remi/archive/<run_id>/sessions.jsonThis repo includes helper scripts in scripts/:
scripts/remi-diary.sh— generate a daily Markdown summary fromremi.db, with optional Telegram send.scripts/markie-export.sh— render Markdown to SVG/PNG using localmarkieCLI (MarkieCli).
Example diary usage:
# Generate today's diary markdown
scripts/remi-diary.sh --date today
# Generate and send yesterday's diary image to Telegram
scripts/remi-diary.sh --date yesterday --sendExample Markdown → SVG rendering:
scripts/markie-export.sh \
--input ~/diary/remi/$(date +%F).md \
--output /tmp/remi-diary.svg \
--format svgremi-diary.sh prints a safety warning by default because it may send transcript data to external services:
- your configured summary command/provider (default:
codex exec ...) for summary generation - Telegram (when
--sendis enabled)
If you intentionally want to suppress the warning:
DIARY_SKIP_EXTERNAL_WARNING=1 scripts/remi-diary.sh --date todayUse DIARY_* environment overrides (shown in scripts/remi-diary.sh --help) to adapt paths/commands for your environment.
Workspace crates:
core-model: canonical types + adapter trait + deterministic IDsstore-sqlite: SQLite schema, upserts, FTS index maintenance, archive planning helpersingest: sync orchestration with progress phasessearch: lexical + recency (+ optional semantic) rankingarchive: plan/run/restore archive workflowsadapter-common(atcrates/adapters/common): shared file/JSON parsing + cursor logicadapters/{pi,droid,opencode,claude,amp,codex}: per-agent ingestion adaptersembeddings(optional): ONNX + tokenizer embedding generationcli:remicommand-line interface
GitHub release workflow publishes:
remi-linux-x64-simple.tar.gz(binary only)remi-linux-x64-bundled.tar.gz(binary + ONNX Runtime + BGE model files)
As of v0.0.4 (February 11, 2026), published assets are Linux x64.
The workflow in this repo is set up to also produce macOS/Windows simple artifacts on future tagged releases.
Homebrew tap setup (recommended layout):
- Create a tap repo, e.g.
lsj5031/homebrew-remi. - Start from this repo’s
Formula/remi.rband update URL/version/SHA per tagged release. - Update SHA256 per release.
End-user install:
brew tap lsj5031/remi
brew install remiDual-licensed under:
- MIT
- Apache-2.0
