fix(mem0-plugin): v0.2.2 (#5234)

This commit is contained in:
Kartik
2026-05-22 21:47:14 +05:30
committed by GitHub
parent 53a3998873
commit 16a7702d09
41 changed files with 889 additions and 675 deletions
-123
View File
@@ -1,123 +0,0 @@
---
name: mem0-digest
description: >
Summarize recent memory activity for the current project. Shows new memories,
categories touched, and growth trends over the past 7 days.
TRIGGER: user runs /mem0:digest, or asks "weekly summary", "what's new in memory",
"mem0 digest", "memory recap".
---
# Mem0 Weekly Digest
Summarize recent memory activity for the current project.
## Execution
### Step 1: Fetch recent memories
Call `search_memories` in parallel with different time-scoped queries:
1. `query="decisions made this week"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"created_at": {"gte": "<7 days ago YYYY-MM-DD>"}}]}`, `limit=20`
2. `query="bugs errors fixes"`, same time filter, `limit=20`
3. `query="patterns conventions learnings"`, same time filter, `limit=20`
Also call `get_memories` with `user_id` + `app_id` to get the full count for comparison.
### Step 2: Deduplicate and analyze
Merge results by memory ID. For each memory, extract:
- `created_at` date
- `categories[0]` or `metadata.type`
- First 100 chars of content
Group into:
- **New this week** (created in last 7 days)
- **Older** (created before, but surfaced by search)
Calculate:
- Total memories in project
- Memories added in last 7 days
- Most active categories this week
- Days with most activity
### Step 3: Display
```
## mem0 Weekly Digest — <project_id>
Period: <start_date> to <today>
### New Memories This Week: <N>
<category>: <count>
- <memory summary, 80 chars> (<date>)
- ...
<category>: <count>
- ...
### Activity Pattern
Most active day: <day> (<N> memories)
Categories touched: <list>
### Project Totals
Total memories: <N> (up <N> from last week)
Top categories: <top 3 by count>
### Highlights
<2-3 sentence summary of the most important decisions, learnings, or patterns stored this week>
```
### Step 4: Write digest to file
After displaying, write the digest to `~/.mem0/weekly-digest.md` for persistence
and external consumption (email, Slack, etc.):
```bash
mkdir -p ~/.mem0
```
Write the full digest output (same markdown shown in terminal) to `~/.mem0/weekly-digest.md`
using the Write tool. **Overwrite** the file each time — it always contains the latest digest.
Also append a one-line summary to `~/.mem0/digest-history.log` for trend tracking:
```bash
echo "<YYYY-MM-DD> | <project_id> | +<new_count> memories | top: <top_category>" >> ~/.mem0/digest-history.log
```
Print at the end:
```
Digest saved to ~/.mem0/weekly-digest.md
```
### Step 5: Schedule recurring digests
When invoked with `--schedule` (e.g., `/mem0:digest --schedule weekly`), register
a cloud routine via Claude Code's `/schedule` command:
```
/schedule <frequency> /mem0:digest
```
For example:
- `/schedule weekly on Monday 9am /mem0:digest` — digest every Monday morning
- `/schedule daily at 8am /mem0:digest` — daily digest
Print:
```
Digest scheduled: <frequency>
Manage at: https://claude.ai/code/routines
```
If `/schedule` is unavailable, print a cron one-liner the user can install manually:
```bash
# macOS/Linux — weekly Monday 9am
(crontab -l 2>/dev/null; echo "0 9 * * 1 cd PROJECT_DIR && claude -p '/mem0:digest' >> /tmp/mem0-digest.log 2>&1") | crontab -
```
### Step 6: Empty state
If no memories in the last 7 days:
```
No new memories in the past week for <project_id>.
Total project memories: <N>.
Tip: mem0 captures learnings automatically as you work. Start coding!
```
+52
View File
@@ -235,6 +235,58 @@ In auto mode:
)
```
## Forget mode (targeted deletion)
When invoked with `--forget` (e.g., `/mem0:dream --forget auth module decisions`
or `/mem0:dream --forget <memory_id>`), skip consolidation and go straight to
search-confirm-delete:
### F1: Parse input
The argument after `--forget` is either:
- A search query: `/mem0:dream --forget auth module decisions`
- A memory ID: `/mem0:dream --forget <memory_id>`
If no argument after `--forget`, ask: "What should I forget? Provide a search query or memory ID."
### F2: Find memories
**If memory ID provided** (looks like a UUID or hex string):
- Call `get_memory` with the ID to verify it exists.
- Show: `Found: "<memory content first 120 chars>" (created <date>)`
**If search query provided:**
- Call `search_memories` with:
- `query=<user's query>`
- `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<project_id>"}]}`
- `limit=10`
- Show numbered list:
```
Found <N> memories matching "<query>":
1. <content, 120 chars> (type: <type>, created: <date>) [ID: <short_id>]
2. ...
```
### F3: Confirm
Ask: "Delete which memories? Enter numbers (e.g., 1,3,5), 'all', or 'cancel'."
For a single memory ID: "Delete this memory? [y/N]"
**Never delete without confirmation.**
### F4: Delete and report
Call `delete_memory` for each confirmed entry. Report: `Deleted <N> memories.`
### Undo recent writes
If the user says "undo last N memories" or "undo last write":
1. Run `python3 "$SCRIPT_DIR/session_stats.py" peek` to get `recent_ids`.
2. Show last N entries, ask for confirmation.
3. Delete confirmed entries via `delete_memory`.
---
## Scheduling recurring dreams
When invoked with `--schedule` (e.g., `/mem0:dream --schedule weekly`), register a
-76
View File
@@ -1,76 +0,0 @@
---
name: mem0-forget
description: >
Delete memories by search query or memory ID. Shows matches for confirmation
before deleting. Safe — always confirms before destructive action.
TRIGGER: user runs /mem0:forget <query>, or says "forget this", "delete memory",
"remove that memory about X".
---
# Mem0 Forget
Delete specific memories from mem0.
## Execution
### Step 1: Parse input
The user provides either:
- A search query: `/mem0:forget auth module decisions`
- A memory ID: `/mem0:forget <memory_id>`
If no argument, ask: "What should I forget? Provide a search query or memory ID."
### Step 2: Find memories
**If memory ID provided** (looks like a UUID or hex string):
- Call `get_memory` with the ID to verify it exists.
- Show: `Found: "<memory content first 120 chars>" (created <date>)`
**If search query provided:**
- Call `search_memories` with:
- `query=<user's query>`
- `user_id=<active_user_id>`
- `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<project_id>"}]}`
- `limit=10`
- Show numbered list:
```
Found <N> memories matching "<query>":
1. <content, 120 chars> (type: <type>, created: <date>) [ID: <short_id>]
2. ...
```
### Step 3: Confirm
Ask: "Delete which memories? Enter numbers (e.g., 1,3,5), 'all', or 'cancel'."
For a single memory ID, ask: "Delete this memory? [y/N]"
**Never delete without confirmation.** This is destructive.
### Step 4: Delete
For each confirmed memory, call `delete_memory` with the memory ID.
### Step 5: Report
```
Deleted <N> memories.
```
If any deletions failed, report which ones and why.
## Undo recent writes
If the user says "undo last N memories" or "undo last write":
1. Read session stats to get recently written memory IDs:
```bash
SCRIPT_DIR="${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CURSOR_PLUGIN_ROOT:-}}}/scripts"
python3 "$SCRIPT_DIR/session_stats.py" peek
```
2. Parse the `recent_ids` array from the JSON output. Each entry has `id`, `category`, `ts`.
3. Show the last N entries (default 1) and ask for confirmation.
4. Delete confirmed entries via `delete_memory`.
If `recent_ids` is empty, tell the user: "No recent memory IDs tracked this session. Use a search query instead."
@@ -1,106 +0,0 @@
---
name: mem0-import-tools
description: >
Import memories from competing AI tool configuration files into mem0.
Supports Cursor (.cursorrules), GitHub Copilot (.github/copilot-instructions.md),
Cline (memory-bank/), and Continue (.continue/rules.md).
TRIGGER: user runs /mem0:import-tools, or asks "import from cursor",
"import cursorrules", "import from cline", "import from copilot",
"import from continue", "migrate from cursor", "migrate memories".
---
# Mem0 Import from Competing Tools
Import configuration and memory files from other AI coding tools into mem0.
## Supported Tools
| Tool | Default file/directory |
|------|----------------------|
| Cursor | `.cursorrules` |
| GitHub Copilot | `.github/copilot-instructions.md` |
| Cline | `memory-bank/` (directory of `.md` files) |
| Continue | `.continue/rules.md` |
## Execution
### Step 1: Detect which tool files exist
Check for the presence of each tool's file/directory in the current working directory:
```bash
# Check each location
test -f .cursorrules && echo "cursor: .cursorrules"
test -f .github/copilot-instructions.md && echo "copilot: .github/copilot-instructions.md"
test -d memory-bank/ && echo "cline: memory-bank/"
test -f .continue/rules.md && echo "continue: .continue/rules.md"
```
### Step 2: Report findings and ask user
List all found files to the user. For example:
```
Found the following tool configuration files:
[1] Cursor rules: .cursorrules
[2] Cline memory bank: memory-bank/
Which would you like to import? (enter numbers, comma-separated, or "all"):
```
If no files are found, print:
```
No competing tool configuration files found in the current directory.
Checked: .cursorrules, .github/copilot-instructions.md, memory-bank/, .continue/rules.md
```
and stop.
### Step 3: Run the import script for each selected tool
Determine the plugin root. Use the appropriate variable for the current platform:
- Claude Code: `${CLAUDE_PLUGIN_ROOT}`
- Codex: `${CODEX_PLUGIN_ROOT}`
- Cursor: `${CURSOR_PLUGIN_ROOT}`
For each tool the user selected, run the corresponding sub-command:
**Cursor (.cursorrules):**
```bash
python3 "<PLUGIN_ROOT>/scripts/import_competing_tools.py" cursorrules --path .cursorrules
```
**GitHub Copilot:**
```bash
python3 "<PLUGIN_ROOT>/scripts/import_competing_tools.py" copilot --path .github/copilot-instructions.md
```
**Cline:**
```bash
python3 "<PLUGIN_ROOT>/scripts/import_competing_tools.py" cline --path memory-bank/
```
**Continue:**
```bash
python3 "<PLUGIN_ROOT>/scripts/import_competing_tools.py" continue --path .continue/rules.md
```
### Step 4: Report results
After each script runs, echo its output to the user. Then print a combined summary:
```
Import complete.
Cursor: <N> memories
Copilot: <N> memories
Total: <N> memories imported into project <project_id>
```
Adjust the summary to reflect only the tools that were actually imported.
## Notes
- Memories are imported with `infer=False` — no AI inference is applied, content is stored as-is.
- Each section or file becomes a separate memory tagged with `metadata.source=<tool>-import` and `metadata.type=project_profile`.
- Sections shorter than 50 characters are automatically skipped (too short to be useful).
- Content longer than 10,000 characters is automatically truncated per chunk.
- You can re-run this skill safely — duplicate content will be caught by mem0's deduplication.
+81
View File
@@ -98,6 +98,87 @@ If any failed:
Imported <N>/<total> memories into project <project_id> (<failed> failed)
```
## Importing from competing AI tools (`--tools`)
When invoked with `--tools` (e.g., `/mem0:import --tools`), detect and import
from competing AI tool configuration files:
### Supported tools
| Tool | File/directory |
|------|---------------|
| Cursor | `.cursorrules` |
| GitHub Copilot | `.github/copilot-instructions.md` |
| Cline | `memory-bank/` (directory of `.md` files) |
| Continue | `.continue/rules.md` |
### T1: Detect
```bash
test -f .cursorrules && echo "cursor: .cursorrules"
test -f .github/copilot-instructions.md && echo "copilot: .github/copilot-instructions.md"
test -d memory-bank/ && echo "cline: memory-bank/"
test -f .continue/rules.md && echo "continue: .continue/rules.md"
```
### T2: Ask user
List found files, ask which to import (numbers, comma-separated, or "all").
If none found:
```
No competing tool configuration files found.
Checked: .cursorrules, .github/copilot-instructions.md, memory-bank/, .continue/rules.md
```
### T3: Run import
For each selected tool:
```bash
python3 "<PLUGIN_ROOT>/scripts/import_competing_tools.py" <tool> --path <file>
```
Tools: `cursorrules`, `copilot`, `cline`, `continue`.
### T4: Report
```
Import complete.
Cursor: <N> memories
Copilot: <N> memories
Total: <N> memories imported into project <project_id>
```
Notes: `infer=False`, tagged `metadata.source=<tool>-import`, sections <50 chars
skipped, chunks >10k chars truncated, safe to re-run (deduplication handles it).
---
## Importing Claude Code's native MEMORY.md
When invoked with a path to Claude Code's native `MEMORY.md` file (typically
`~/.claude/projects/<proj-key>/memory/MEMORY.md`), or when `on_session_start.sh`
detects native auto-memory and the user chooses to import:
1. Read the file. It contains newline-separated memory entries (one fact per line,
sometimes with `- ` bullet prefix).
2. Split by non-empty lines. Each line becomes one memory.
3. Skip lines shorter than 20 characters or lines that are just headers (`#`).
4. For each line, call `add_memory` with:
- `messages=[{"role": "user", "content": "<line>"}]`
- `user_id=<active_user_id>`
- `app_id=<active_project_id>`
- `metadata={"type": "task_learning", "source": "memory-md-import", "confidence": 0.8}`
- `infer=False`
5. Report: `Imported <N> memories from MEMORY.md into project <project_id>`
6. Suggest disabling native auto-memory:
```
To avoid duplicate memory systems, add to ~/.claude/settings.json:
"autoMemoryEnabled": false
```
This handles the cold-start gap when a user has been using Claude Code's native
memory and switches to mem0.
## Error Handling
- If the parser script is not found at `<PLUGIN_ROOT>/scripts/parse_export_file.py`, print an error and stop.
@@ -0,0 +1,71 @@
---
name: mem0-list-projects
description: >
List all project scopes (app_ids) that have stored memories for the current
user. Essential for /mem0:switch-project discoverability and cross-project
workflows.
TRIGGER: user runs /mem0:list-projects, or asks "what projects does mem0 know",
"list my mem0 projects", "show all projects", "which app_ids exist".
---
# Mem0 List Projects
Show all known project scopes for the current user.
## Execution
### Step 1: Fetch memories to discover app_ids
There is no dedicated "list projects" API endpoint. Discover projects by fetching
the user's memories and extracting distinct `app_id` values.
Call `get_memories` with:
- `user_id=<active_user_id>`
- `page_size=200`
Do NOT pass `app_id` — we want memories across ALL projects.
If the response indicates more pages, paginate until all are fetched (up to 1000
memories max to avoid excessive API calls).
### Step 2: Extract distinct projects
For each memory, read the `app_id` field (may also appear as `metadata.app_id`
on older memories). Collect distinct values.
For each project, count:
- Total memories
- Most recent `created_at` date
- Top 3 `metadata.type` values by frequency
### Step 3: Display
```
## mem0 Projects for <user_id>
| Project | Memories | Last Active | Top Categories |
|---------|----------|-------------|---------------|
| <app_id_1> | <count> | <date> | decision, convention, anti_pattern |
| <app_id_2> | <count> | <date> | task_learning, environmental |
| ... | | | |
Active project: <current_project_id> ← (current)
Total: <N> projects, <M> total memories
```
Mark the current project with `← (current)`.
### Step 4: Empty state
If zero memories found:
```
No projects found for user <user_id>.
Run /mem0:onboard in a project directory to get started.
```
### Step 5: Suggest next actions
```
Switch project: /mem0:switch-project <name>
Search across all: /mem0:tour --all-projects
```
+40
View File
@@ -49,6 +49,21 @@ filters={"AND": [
Empty results are normal. Proceed without context — they don't mean the system is broken.
### Contradiction detection at search time
After receiving search results, scan for contradictions before using them:
1. If 2+ results address the **same topic** (same `metadata.type`, overlapping file paths or entity names) but assert **opposing facts**, surface BOTH to the user instead of silently picking one.
2. Format:
```
⚠️ Conflicting memories found:
- [mem0:<id1>] "<content1>" (confidence: <score1>, <date1>)
- [mem0:<id2>] "<content2>" (confidence: <score2>, <date2>)
Which is current?
```
3. After the user resolves: update the loser via `update_memory` to mark it superseded, or delete it. Store the winner's fact as authoritative if not already.
4. If the user doesn't resolve, default to the more recent memory with higher confidence, but note the ambiguity in your response.
### How to search well
When you do search, run **2–4 parallel** `search_memories` calls at different angles instead of one query echoing the user's prompt.
@@ -130,6 +145,31 @@ search_memories(query="auth",
Extract key learnings and store them using the `add_memory` tool:
### REQUIRED metadata fields
Every `add_memory` call MUST include these metadata fields. Do NOT omit them:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | YES | Memory category: `decision`, `task_learning`, `anti_pattern`, `convention`, `user_preference`, `environmental`, `session_state`, `compact_summary` |
| `confidence` | float | YES | 0.0–1.0 confidence score. Default: `0.7` for inferred learnings, `0.9` for explicit user statements |
| `files` | list[str] | YES | File paths relevant to this memory. Use `["*"]` for project-wide learnings |
| `source` | string | YES | How the memory was captured: `user_request`, `auto_capture`, `post_commit`, `error_recovery` |
**Example:**
```json
{
"metadata": {
"type": "decision",
"confidence": 0.9,
"files": ["src/auth/login.py", "src/auth/middleware.py"],
"source": "user_request"
}
}
```
**If you omit `confidence` or `files`, the memory will be harder to rank and retrieve later.**
- **Decisions made** -> Include metadata `{"type": "decision"}`
- **Strategies that worked** -> Include metadata `{"type": "task_learning"}`
- **Failed approaches** -> Include metadata `{"type": "anti_pattern"}`
+1 -1
View File
@@ -82,7 +82,7 @@ Then retry the categories script.
## Step 5: Mark project as onboarded
Create a marker file so SessionStart won't re-trigger onboarding next session:
The marker file is already created by `on_session_start.sh` on first display of the onboard prompt. Touch it here for idempotency:
```bash
_SAFE_PID=$(printf '%s' "<active_project_id>" | tr '/:' '--')
-46
View File
@@ -1,46 +0,0 @@
---
name: mem0-peek
description: >
Quick search — compact one-liner results. Faster and lighter than /mem0:tour.
Takes a search query as argument.
TRIGGER: user runs /mem0:peek <query>, or says "quick search mem0",
"what do we know about X", "peek at memories about Y".
---
# Mem0 Peek
Quick search with compact output. Lighter than `/mem0:tour`.
## Execution
### Step 1: Parse query
The user provides a search query: `/mem0:peek auth middleware`
If no query provided, ask: "What should I search for?"
### Step 2: Search
Run 2 parallel `search_memories` calls:
1. Broad: `query=<user's query>`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `limit=10`
2. Targeted: `query=<user's query>`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"metadata": {"type": "decision"}}]}`, `limit=5`
### Step 3: Display
Deduplicate by ID, then show compact results:
```
## mem0 peek: "<query>" (<N> results)
1. [decision] Auth module uses JWT with RS256 keys (2025-05-15) [mem0:a3f8b2c1]
2. [anti_pattern] Don't use symmetric HS256 — leaked in env (2025-05-10) [mem0:7e2d9f4a]
3. [convention] All middleware in src/middleware/ (2025-05-08) [mem0:c4d5e6f7]
```
Format: `<number>. [<type>] <content, 80 chars> (<date>) [mem0:<short_id>]`
If no results:
```
No memories matching "<query>" for project <project_id>.
```
+34 -5
View File
@@ -1,10 +1,12 @@
---
name: mem0-pin
description: >
Pin important memories so they surface prominently. Updates metadata to mark
a memory as pinned. Pinned memories should be prioritized during search.
TRIGGER: user runs /mem0:pin <query or ID>, or says "pin this memory",
"mark as important", "always remember this".
Pin important memories so they surface prominently and are protected from
consolidation. New pins use immutable: true (SDK v2.1.33+) to prevent
deduplication from modifying or removing the memory. Existing memories get
metadata.pinned: true as a search-time filter; full consolidation protection
requires delete + re-add. TRIGGER: user runs /mem0:pin <query or ID>, or
says "pin this memory", "mark as important", "always remember this".
---
# Mem0 Pin
@@ -35,12 +37,28 @@ This is required because `update_memory` replaces the full memory — a metadata
### Step 3: Pin it
There are two sub-cases depending on whether the user wants to pin an **existing** memory or create a **new** pinned memory from scratch.
#### 3a: Pinning a new memory (preferred path for full protection)
Use `add_memory` with `immutable: true` as a top-level parameter. The `immutable` flag is a first-class platform parameter (added in SDK v2.1.33) that prevents the memory from being modified or removed by consolidation/deduplication. `metadata.pinned: true` is also included as a search-time filter aid.
```python
add_memory(
messages=[{"role": "user", "content": "<text to pin>"}],
user_id=<user_id>,
immutable=True,
metadata={"pinned": True},
)
```
#### 3b: Pinning an existing memory
Call `update_memory` with:
- `memory_id=<selected_id>`
- `data=<original_text>` (preserve the existing content)
- `metadata=` merge `original_metadata` with `{"pinned": true}`
Example:
```python
updated_meta = {**original_metadata, "pinned": True}
update_memory(memory_id=<selected_id>, data=<original_text>, metadata=updated_meta)
@@ -48,12 +66,23 @@ update_memory(memory_id=<selected_id>, data=<original_text>, metadata=updated_me
**Important:** `update_memory` requires the `data` (text) parameter. Passing only metadata may error or wipe content. Always read first, then update with the full text and explicit metadata.
**Consolidation-protection limitation:** `update_memory` cannot set the `immutable` flag on an existing memory. If the user needs full consolidation protection for an existing memory, they must delete it and re-add it using `add_memory` with `immutable: true` (path 3a above). In the confirm step (Step 4), note this limitation if the user pinned an existing memory via `update_memory`.
### Step 4: Confirm
For new pins created via `add_memory` with `immutable: true`:
```
Pinned: "<memory content, first 80 chars>..."
Memory ID: <id>
Pinned with consolidation protection (immutable). This memory will not be modified or removed by deduplication.
```
For existing memories pinned via `update_memory`:
```
Pinned: "<memory content, first 80 chars>..."
Memory ID: <id>
Pinned memories surface first when relevant to a search.
Note: consolidation protection (immutable flag) requires delete + re-add. Say "re-pin this with full protection" to do that.
```
### Unpin
+53
View File
@@ -94,3 +94,56 @@ Print a compact dashboard with an ASCII histogram for category distribution:
- **Access count buckets:** Read `metadata.access_count` (default 0 if absent). Buckets: 0, 1–5, 6–20, 20+.
Skip any section with zero data.
## Weekly digest mode
When invoked with `--weekly` (e.g., `/mem0:stats --weekly`), append a weekly
activity digest after the standard stats dashboard:
### W1: Fetch recent memories
Call `search_memories` in parallel with time-scoped queries:
1. `query="decisions made this week"`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"created_at": {"gte": "<7 days ago YYYY-MM-DD>"}}]}`, `limit=20`
2. `query="bugs errors fixes"`, same time filter, `limit=20`
3. `query="patterns conventions learnings"`, same time filter, `limit=20`
### W2: Analyze
Merge by ID. Group into "New this week" by `categories[0]` or `metadata.type`.
Calculate: memories added last 7 days, most active categories, most active day.
### W3: Display
Append after the standard stats:
```
### Weekly Digest (<start_date> to <today>)
New Memories This Week: <N>
<category>: <count>
- <memory summary, 80 chars> (<date>)
- ...
Activity Pattern
Most active day: <day> (<N> memories)
Categories touched: <list>
Highlights
<2-3 sentence summary of most important decisions/learnings this week>
```
### W4: Write digest file
Write to `~/.mem0/weekly-digest.md` (overwrite). Append one-line to
`~/.mem0/digest-history.log`:
```
<YYYY-MM-DD> | <project_id> | +<new_count> memories | top: <top_category>
```
### W5: Empty state
If no new memories in 7 days:
```
No new memories in the past week for <project_id>.
Total project memories: <N>.
```
+49
View File
@@ -11,6 +11,55 @@ description: >
Show the user what mem0 has stored for the current project.
## Cross-project mode
When invoked with `--all-projects` (e.g., `/mem0:tour --all-projects` or
`/mem0:tour --all-projects auth middleware`), search across ALL projects:
1. Call `get_memories` with `user_id=<active_user_id>`, `page_size=200` — **no `app_id` filter**.
2. If a search query was also provided, run `search_memories` with `query=<query>`,
`filters={"AND": [{"user_id": "<id>"}]}`, `limit=20` — again no `app_id`.
3. Group results by `app_id` first, then by category within each project.
4. Display:
```
## Cross-Project Tour for <user_id>
### <app_id_1> (<N> memories)
#### Architecture Decisions
- <memory content>
...
### <app_id_2> (<N> memories)
...
---
Total: <N> memories across <M> projects
```
5. Mark the current project with `← (current)` in the heading.
If `--all-projects` is NOT present, use the standard single-project flow below.
## Peek mode (compact search)
When `/mem0:tour` receives a search query argument (e.g., `/mem0:tour auth middleware`)
WITHOUT `--all-projects`, run in **peek mode** — compact one-liner results:
1. Run 2 parallel `search_memories` calls:
- Broad: `query=<query>`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}`, `limit=10`
- Targeted: `query=<query>`, `filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"metadata": {"type": "decision"}}]}`, `limit=5`
2. Deduplicate by ID, display compact results:
```
## mem0 search: "<query>" (<N> results)
1. [decision] Auth module uses JWT with RS256 keys (2025-05-15) [mem0:a3f8b2c1]
2. [anti_pattern] Don't use symmetric HS256 — leaked in env (2025-05-10) [mem0:7e2d9f4a]
3. [convention] All middleware in src/middleware/ (2025-05-08) [mem0:c4d5e6f7]
```
Format: `<number>. [<type>] <content, 80 chars> (<date>) [mem0:<short_id>]`
3. If no results: `No memories matching "<query>" for project <project_id>.`
If no query argument and no `--all-projects` flag, use the full tour flow below.
## Execution
### Step 1: Fetch ALL memories for this project