remem-mcp 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -125
- package/dist/chunk-FA324IBN.js +903 -0
- package/dist/chunk-FA324IBN.js.map +1 -0
- package/dist/{chunk-ULMM6LKD.js → chunk-X4ECGLYH.js} +60 -16
- package/dist/chunk-X4ECGLYH.js.map +1 -0
- package/dist/chunk-XK4Y53J2.js +54 -0
- package/dist/chunk-XK4Y53J2.js.map +1 -0
- package/dist/{engine-EIOBO7ZE.js → engine-LVKGZHBY.js} +5 -2
- package/dist/index.js +1234 -185
- package/dist/index.js.map +1 -1
- package/dist/resolver-AVK7XKX7.js +300 -0
- package/dist/resolver-AVK7XKX7.js.map +1 -0
- package/dist/sdk.js +3 -2
- package/dist/storage/schema.sql +6 -2
- package/package.json +1 -2
- package/scripts/dogfood-claude-cli.sh +156 -0
- package/scripts/dogfood-codex.sh +145 -0
- package/skills/remem-mcp/SKILL.md +45 -91
- package/dist/chunk-SHLLMMMU.js +0 -480
- package/dist/chunk-SHLLMMMU.js.map +0 -1
- package/dist/chunk-ULMM6LKD.js.map +0 -1
- /package/dist/{engine-EIOBO7ZE.js.map → engine-LVKGZHBY.js.map} +0 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# dogfood-codex.sh — dogfood remem-mcp using OpenAI Codex CLI as the agent
|
|
3
|
+
# Codex CLI gets remem-mcp as its MCP server, then works on remem-mcp's own codebase.
|
|
4
|
+
#
|
|
5
|
+
# Usage: bash scripts/dogfood-codex.sh [max_iterations] [model]
|
|
6
|
+
# Example: bash scripts/dogfood-codex.sh 3 gpt-5-codex
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
cd "$(dirname "$0")/.."
|
|
10
|
+
|
|
11
|
+
MAX_ITER="${1:-3}"
|
|
12
|
+
MODEL="${2:-gpt-5.5}"
|
|
13
|
+
REPO_DIR="$(pwd)"
|
|
14
|
+
TMP_DIR="/tmp/remem-dogfood-codex"
|
|
15
|
+
mkdir -p "$TMP_DIR"
|
|
16
|
+
|
|
17
|
+
echo "══════════════════════════════════════════════════════════════"
|
|
18
|
+
echo " 🐕 DOGFOOD WITH CODEX CLI"
|
|
19
|
+
echo " Repo: $REPO_DIR"
|
|
20
|
+
echo " Model: $MODEL"
|
|
21
|
+
echo " Iterations: $MAX_ITER"
|
|
22
|
+
echo " MCP: remem-mcp (already configured via 'codex mcp list')"
|
|
23
|
+
echo "══════════════════════════════════════════════════════════════"
|
|
24
|
+
echo ""
|
|
25
|
+
|
|
26
|
+
# Build first
|
|
27
|
+
echo "[build] Compiling..."
|
|
28
|
+
npm run build 2>&1 | tail -1
|
|
29
|
+
echo ""
|
|
30
|
+
|
|
31
|
+
# Verify remem-mcp is configured for Codex
|
|
32
|
+
if ! codex mcp list 2>&1 | grep -q "remem-mcp"; then
|
|
33
|
+
echo "⚠ remem-mcp not configured for Codex. Adding it now..."
|
|
34
|
+
codex mcp add remem-mcp \
|
|
35
|
+
--env "REMEM_DB_PATH=$HOME/.local/share/remem-mcp/memory.db" \
|
|
36
|
+
--env "REMEM_GLOBAL_SESSION_KEY=global" \
|
|
37
|
+
--env "REMEM_AUTO_GLOBAL=true" \
|
|
38
|
+
-- node "$REPO_DIR/dist/index.js"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
ITER=0
|
|
42
|
+
while [ "$ITER" -lt "$MAX_ITER" ]; do
|
|
43
|
+
ITER=$((ITER + 1))
|
|
44
|
+
echo ""
|
|
45
|
+
echo "────────────────────────────────────────────────────────────"
|
|
46
|
+
echo " ITERATION $ITER/$MAX_ITER"
|
|
47
|
+
echo "────────────────────────────────────────────────────────────"
|
|
48
|
+
|
|
49
|
+
# 1. Snapshot current state
|
|
50
|
+
echo ""
|
|
51
|
+
echo "[1/4] State snapshot:"
|
|
52
|
+
TS_ERRS=$(npx tsc --noEmit 2>&1 | grep -c "error TS" | tr -d '[:space:]' || echo "0")
|
|
53
|
+
TEST_OUT=$(npx vitest run 2>&1 || true)
|
|
54
|
+
TEST_FAILS=$(echo "$TEST_OUT" | grep -oE "[0-9]+ failed" | head -1 | grep -oE "[0-9]+" | tr -d '[:space:]' || echo "0")
|
|
55
|
+
TEST_PASSES=$(echo "$TEST_OUT" | grep -oE "[0-9]+ passed" | head -1 | grep -oE "[0-9]+" | tr -d '[:space:]' || echo "0")
|
|
56
|
+
[ -z "$TS_ERRS" ] && TS_ERRS=0
|
|
57
|
+
[ -z "$TEST_FAILS" ] && TEST_FAILS=0
|
|
58
|
+
[ -z "$TEST_PASSES" ] && TEST_PASSES=0
|
|
59
|
+
echo " TS errors: $TS_ERRS | Tests: $TEST_PASSES passed, $TEST_FAILS failed"
|
|
60
|
+
|
|
61
|
+
# 2. Capture errors to feed Codex context
|
|
62
|
+
ERR_FILE="$TMP_DIR/errors-iter-$ITER.txt"
|
|
63
|
+
{
|
|
64
|
+
echo "## Build errors (iteration $ITER)"
|
|
65
|
+
npm run build 2>&1 | grep -i "error\|fail" | head -20 || echo "none"
|
|
66
|
+
echo ""
|
|
67
|
+
echo "## TypeScript errors"
|
|
68
|
+
npx tsc --noEmit 2>&1 | grep "error TS" | head -20 || echo "none"
|
|
69
|
+
echo ""
|
|
70
|
+
echo "## Test failures"
|
|
71
|
+
echo "$TEST_OUT" | grep -B2 "FAIL\|AssertionError\|Error:" | head -30 || echo "none"
|
|
72
|
+
} > "$ERR_FILE" 2>&1
|
|
73
|
+
|
|
74
|
+
ERR_COUNT=$(grep -c "error\|fail\|FAIL" "$ERR_FILE" 2>/dev/null || echo "0")
|
|
75
|
+
echo " Error file: $ERR_FILE ($ERR_COUNT lines with errors)"
|
|
76
|
+
|
|
77
|
+
# 3. Run Codex CLI
|
|
78
|
+
echo ""
|
|
79
|
+
echo "[2/4] Launching Codex CLI (model=$MODEL)..."
|
|
80
|
+
|
|
81
|
+
PROMPT="You are working on the remem-mcp codebase (a local MCP memory server at $REPO_DIR).
|
|
82
|
+
|
|
83
|
+
Current state:
|
|
84
|
+
- TypeScript errors: $TS_ERRS
|
|
85
|
+
- Test failures: $TEST_FAILS (out of $TEST_PASSES passed)
|
|
86
|
+
|
|
87
|
+
Error details from this iteration:
|
|
88
|
+
$(cat "$ERR_FILE")
|
|
89
|
+
|
|
90
|
+
Your tasks:
|
|
91
|
+
1. Use the remem-mcp MCP tools (recall, search) to check if we've seen these errors before and how we fixed them.
|
|
92
|
+
2. Fix the TypeScript errors and test failures shown above.
|
|
93
|
+
3. After fixing, run \`npm run build\` and \`npx vitest run\` to verify.
|
|
94
|
+
4. Use the remem-mcp capture tool to store what you fixed and how, so future sessions can recall it.
|
|
95
|
+
5. If everything passes, look for edge cases or potential bugs in the codebase and fix them.
|
|
96
|
+
|
|
97
|
+
Focus on real fixes, not workarounds. Check src/ for the relevant code."
|
|
98
|
+
|
|
99
|
+
codex exec \
|
|
100
|
+
--model "$MODEL" \
|
|
101
|
+
--sandbox workspace-write \
|
|
102
|
+
--dangerously-bypass-approvals-and-sandbox \
|
|
103
|
+
"$PROMPT" \
|
|
104
|
+
2>&1 | tee "$TMP_DIR/codex-output-iter-$ITER.log" || true
|
|
105
|
+
|
|
106
|
+
echo ""
|
|
107
|
+
echo "[3/4] Codex CLI finished. Output saved to $TMP_DIR/codex-output-iter-$ITER.log"
|
|
108
|
+
|
|
109
|
+
# 4. Re-check state after Codex's fixes
|
|
110
|
+
echo ""
|
|
111
|
+
echo "[4/4] Post-fix state:"
|
|
112
|
+
TS_ERRS_AFTER=$(npx tsc --noEmit 2>&1 | grep -c "error TS" | tr -d '[:space:]' || echo "0")
|
|
113
|
+
TEST_OUT_AFTER=$(npx vitest run 2>&1 || true)
|
|
114
|
+
TEST_FAILS_AFTER=$(echo "$TEST_OUT_AFTER" | grep -oE "[0-9]+ failed" | head -1 | grep -oE "[0-9]+" | tr -d '[:space:]' || echo "0")
|
|
115
|
+
TEST_PASSES_AFTER=$(echo "$TEST_OUT_AFTER" | grep -oE "[0-9]+ passed" | head -1 | grep -oE "[0-9]+" | tr -d '[:space:]' || echo "0")
|
|
116
|
+
[ -z "$TS_ERRS_AFTER" ] && TS_ERRS_AFTER=0
|
|
117
|
+
[ -z "$TEST_FAILS_AFTER" ] && TEST_FAILS_AFTER=0
|
|
118
|
+
[ -z "$TEST_PASSES_AFTER" ] && TEST_PASSES_AFTER=0
|
|
119
|
+
|
|
120
|
+
echo " TS errors: $TS_ERRS → $TS_ERRS_AFTER"
|
|
121
|
+
echo " Test failures: $TEST_FAILS → $TEST_FAILS_AFTER"
|
|
122
|
+
echo " Tests passed: $TEST_PASSES → $TEST_PASSES_AFTER"
|
|
123
|
+
|
|
124
|
+
# Summary
|
|
125
|
+
echo ""
|
|
126
|
+
echo "┌──────────────────────────────────┐"
|
|
127
|
+
echo "│ Iteration $ITER summary:"
|
|
128
|
+
echo "│ TS errors: $TS_ERRS → $TS_ERRS_AFTER"
|
|
129
|
+
echo "│ Test fails: $TEST_FAILS → $TEST_FAILS_AFTER"
|
|
130
|
+
echo "│ Tests passed: $TEST_PASSES → $TEST_PASSES_AFTER"
|
|
131
|
+
echo "└──────────────────────────────────┘"
|
|
132
|
+
|
|
133
|
+
if [ "$TS_ERRS_AFTER" -eq 0 ] && [ "$TEST_FAILS_AFTER" -eq 0 ]; then
|
|
134
|
+
echo ""
|
|
135
|
+
echo "★★★ ALL GREEN — 0 TS errors, 0 test failures ★★★"
|
|
136
|
+
echo "Codex CLI + remem-mcp dogfood iteration $ITER succeeded."
|
|
137
|
+
break
|
|
138
|
+
fi
|
|
139
|
+
done
|
|
140
|
+
|
|
141
|
+
echo ""
|
|
142
|
+
echo "══════════════════════════════════════════════════════════════"
|
|
143
|
+
echo " DOGFOOD COMPLETE — $ITER iteration(s)"
|
|
144
|
+
echo " Logs: $TMP_DIR/"
|
|
145
|
+
echo "══════════════════════════════════════════════════════════════"
|
|
@@ -1,140 +1,94 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: remem-mcp
|
|
3
|
-
description: Long-term memory for coding agents.
|
|
3
|
+
description: Long-term memory for coding agents. Auto-applies at the start of any coding task — recall past context before answering, capture decisions/learnings/fixes after work, use CodeGraph instead of grep for symbol lookup. Invoke when you see [remem-mcp] in your context or when starting any non-trivial coding work.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You have a long-term memory server via MCP. Use the tools automatically — do not ask permission.
|
|
7
7
|
|
|
8
8
|
## Tools
|
|
9
9
|
|
|
10
|
-
**Core:** `recall` `capture` `search` `forget` `resolve` `handoff` `adr` `update` `consolidate`
|
|
11
|
-
|
|
12
|
-
**CodeGraph:** `codegraph_search` (auto-indexes on first use) `codegraph_callers` `codegraph_callees` `codegraph_impact` `codegraph_list`
|
|
13
|
-
|
|
10
|
+
**Core:** `recall` `capture` `search` `forget` `resolve` `handoff` `adr` `update` `consolidate` `scenario_create` `persona_update`
|
|
11
|
+
**CodeGraph:** `codegraph_search` (auto-indexes on first use) `codegraph_callers` `codegraph_callees` `codegraph_impact` `codegraph_list` `codegraph_detect_changes` (git diff → affected symbols)
|
|
14
12
|
**Wiki:** `wiki_ingest` `wiki_search` `wiki_get` `wiki_outdated`
|
|
15
13
|
|
|
16
14
|
## Rule 1: Recall before answering
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
Hooks auto-inject BM25-only memory (shallow). **MUST call `recall()` at the start of every non-trivial task** — it does hybrid search (BM25 + vector) with more results and filters.
|
|
19
17
|
|
|
20
18
|
```
|
|
21
|
-
recall({ "query": "<user's question or task>", "mode": "hybrid" })
|
|
19
|
+
recall({ "query": "<user's question or task>", "mode": "hybrid", "limit": 5 })
|
|
22
20
|
```
|
|
23
21
|
|
|
24
|
-
If recall returns nothing, proceed normally. Don't mention the empty result.
|
|
25
|
-
|
|
26
22
|
## Rule 2: Capture after non-trivial work
|
|
27
23
|
|
|
28
|
-
Call `capture` automatically after completing work. Don't ask.
|
|
24
|
+
Call `capture` automatically after completing work. Don't ask. Include `atoms` — short distilled facts that recall returns instead of raw content (90% fewer tokens).
|
|
29
25
|
|
|
30
26
|
```
|
|
31
|
-
capture({
|
|
27
|
+
capture({
|
|
28
|
+
"content": "Chose SQLite over Postgres for zero-setup MVP. SQLite has FTS5 + sqlite-vec built in, no server needed.",
|
|
29
|
+
"type": "decision",
|
|
30
|
+
"tags": ["arch"],
|
|
31
|
+
"atoms": ["Use SQLite (not Postgres) for zero-setup MVP", "SQLite has FTS5 + sqlite-vec built in"]
|
|
32
|
+
})
|
|
32
33
|
```
|
|
33
34
|
|
|
34
|
-
**Types:** `decision` (chose X over Y, include why) · `learning` (non-obvious fact) · `task` (completed work) · `error` (bug + root cause + fix)
|
|
35
|
+
**Types:** `decision` (chose X over Y, include why) · `learning` (non-obvious fact) · `task` (completed work) · `error` (bug + root cause + fix)
|
|
35
36
|
|
|
36
|
-
**
|
|
37
|
+
**Atoms:** 1-3 short self-contained facts. Each useful on its own without the raw content. Write for decisions, learnings, errors. Skip for conversations.
|
|
37
38
|
|
|
38
|
-
## Rule 3:
|
|
39
|
+
## Rule 3: Consolidate atoms into scenarios (L2)
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
When you have 5+ atoms about the same topic, call `scenario_create` to create a high-signal summary. Recall injects scenarios automatically (~100 tokens instead of 5+ atoms).
|
|
41
42
|
|
|
42
43
|
```
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
scenario_create({
|
|
45
|
+
"atom_ids": ["01...", "01...", "01..."],
|
|
46
|
+
"summary": "Database: SQLite chosen for MVP — FTS5 + sqlite-vec built in, zero setup, no server needed.",
|
|
47
|
+
"persona_tags": ["database", "arch"]
|
|
48
|
+
})
|
|
46
49
|
```
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
## Rule 4: Handoff when switching agents
|
|
51
|
-
|
|
52
|
-
Call `handoff` at session end or before switching agents. Creates a packet the next agent loads via `recall`.
|
|
51
|
+
**When:** After capturing 5+ decisions/learnings about the same topic (e.g., database, hooks, deployment).
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
handoff({ "task": "Fix auth bug", "status": "in_progress", "progress": "Found root cause", "next_steps": ["Implement fix"] })
|
|
56
|
-
```
|
|
53
|
+
**Auto-pipeline:** The Stop hook spawns a background worker that auto-extracts L1 atoms from uncaptured L0 entries, auto-consolidates 5+ atoms on the same topic into L2 scenarios, and auto-updates L3 persona from repeated tags. You don't need to call `scenario_create` or `persona_update` manually — the worker does it. Only call them manually if you want a specific summary the worker wouldn't generate.
|
|
57
54
|
|
|
58
|
-
|
|
55
|
+
## Rule 4: Update persona (L3)
|
|
59
56
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Call `forget` ONLY when the user asks to delete. Always require `confirm: true`.
|
|
57
|
+
When you notice a user preference or pattern (2+ occurrences), call `persona_update`. SessionStart AND UserPromptSubmit inject persona automatically every turn (~50 tokens).
|
|
63
58
|
|
|
64
59
|
```
|
|
65
|
-
|
|
60
|
+
persona_update({ "trait": "language", "value": "Vietnamese" })
|
|
61
|
+
persona_update({ "trait": "output_style", "value": "concise" })
|
|
66
62
|
```
|
|
67
63
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
## Trust states
|
|
64
|
+
**When:** User asks for concise output 2+ times, works in a specific language, prefers a framework, uses a specific project.
|
|
71
65
|
|
|
72
|
-
-
|
|
73
|
-
- Use `resolve` when two captures conflict. Use `supersedes` on `capture` to replace an old value.
|
|
74
|
-
|
|
75
|
-
## ADR for architectural decisions
|
|
76
|
-
|
|
77
|
-
Use `adr` (not `capture`) for decisions with context, alternatives, and consequences.
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
adr({ "title": "Use SQLite", "context": "Need zero-setup", "decision": "SQLite + FTS5 + sqlite-vec", "alternatives": ["Postgres+pgvector", "DuckDB"], "consequences": "Single-writer, no remote access" })
|
|
81
|
-
```
|
|
66
|
+
**Auto-pipeline:** The background worker auto-detects tags appearing 2+ times in captures and appends them to persona. Manual `persona_update` is for explicit user preferences the worker can't detect.
|
|
82
67
|
|
|
83
|
-
##
|
|
68
|
+
## Rule 5: Use CodeGraph instead of grep
|
|
84
69
|
|
|
85
|
-
|
|
70
|
+
For function/class/method definitions, call `codegraph_search` — NOT grep. Auto-indexes `src/` on first use.
|
|
86
71
|
|
|
87
72
|
```
|
|
88
|
-
|
|
73
|
+
codegraph_search({ "query": "handleCapture" })
|
|
74
|
+
codegraph_callers({ "symbol_id": "<id from search>" })
|
|
75
|
+
codegraph_detect_changes({ "repo_path": "/abs/path" }) // git diff → affected symbols + risk
|
|
89
76
|
```
|
|
90
77
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- `update` — correct a capture's content/tags. Preserves ID and created_at.
|
|
94
|
-
- `consolidate` — find and merge duplicates. `consolidate({ "threshold": 0.75 })` to dry-run, add `"confirm": true` to merge.
|
|
78
|
+
CodeGraph uses 6-strategy call resolution (import-map → same-module → unique-name → suffix → fuzzy) with confidence scoring. JSX components (`<FleetMap/>`) and method calls (`obj.method()`) are captured. Stdlib calls (fmt.Printf, console.log) are filtered out.
|
|
95
79
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
If `npx remem-mcp install-hooks` was run:
|
|
99
|
-
- **SessionStart** — recent captures injected automatically
|
|
100
|
-
- **PreToolUse** — past errors injected before lint/build/test
|
|
101
|
-
- **PostToolUse** — failed commands auto-captured with root cause
|
|
102
|
-
- **SessionEnd** — session summary auto-captured
|
|
103
|
-
|
|
104
|
-
You can still call tools manually anytime.
|
|
80
|
+
Use grep only for: string literals, config values, file names.
|
|
105
81
|
|
|
106
|
-
##
|
|
82
|
+
## Other tools
|
|
107
83
|
|
|
108
|
-
|
|
84
|
+
- `forget({ "id", "confirm": true })` — only when user asks to delete. `reject: true` blocks re-capture of wrong info.
|
|
85
|
+
- `handoff({ "task", "status", "progress", "next_steps" })` — at session end or before switching agents.
|
|
86
|
+
- `adr({ "title", "context", "decision", "alternatives", "consequences" })` — for architectural decisions.
|
|
87
|
+
- `search({ "query", "filters": { "type", "tags" } })` — when you need specific filters.
|
|
88
|
+
- `resolve` — when two captures conflict. `supersedes` on `capture` replaces old values.
|
|
89
|
+
- `update` — correct a capture's content/tags.
|
|
90
|
+
- `consolidate({ "threshold": 0.75 })` — merge duplicate captures. `scenario_create({ "atom_ids", "summary" })` — create L2 scenario. `persona_update({ "trait", "value" })` — update L3 persona.
|
|
109
91
|
|
|
110
92
|
## Global + project memory
|
|
111
93
|
|
|
112
|
-
Set `REMEM_GLOBAL_SESSION_KEY=global`
|
|
113
|
-
|
|
114
|
-
**How it works:**
|
|
115
|
-
- `recall` and `search` automatically search both project and global memory. Project results appear first, then global.
|
|
116
|
-
- `session_start` returns recent captures from both project and global sessions.
|
|
117
|
-
- 3 slots are reserved for global results so cross-project knowledge isn't buried when project memory is large.
|
|
118
|
-
|
|
119
|
-
**When to store global memory:**
|
|
120
|
-
- Pass `session_key="global"` to `capture` for: coding conventions, tool preferences, recurring patterns, lessons that apply to any project.
|
|
121
|
-
- Or pass `auto_global=true` — server auto-classifies: generic rules/learnings → global, content with file paths/line numbers → project.
|
|
122
|
-
- Don't store global: project-specific bugs, file paths, one-off decisions.
|
|
123
|
-
|
|
124
|
-
**Example:**
|
|
125
|
-
```
|
|
126
|
-
capture(content="Always run tests before committing", type="learning", auto_global=true)
|
|
127
|
-
# → auto-classified as global (no file paths, has "always" signal)
|
|
128
|
-
|
|
129
|
-
capture(content="Fixed bug in src/server.ts line 1418", type="task", auto_global=true)
|
|
130
|
-
# → stays project (has file path)
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## CLI commands
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
npx remem-mcp errors # Error learning dashboard
|
|
137
|
-
npx remem-mcp extract --limit 50 # L1 atom extraction (needs REMEM_LLM_API_KEY)
|
|
138
|
-
npx remem-mcp sync-export # Export memory for team (commit to repo)
|
|
139
|
-
npx remem-mcp sync-import # Import teammate's memory
|
|
140
|
-
```
|
|
94
|
+
Set `REMEM_GLOBAL_SESSION_KEY=global` to enable cross-project memory. `recall`/`search` search both. Pass `auto_global=true` to `capture` for auto-classification (generic → global, file paths → project).
|