Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
473c59f
fix: use epsilon comparison for mtime dedup + add bulk pre-fetch
jphein Apr 10, 2026
8bcae9c
fix: cap search limit, paginate status tools, remove duplicate cache …
jphein Apr 10, 2026
70cf491
perf: batch ChromaDB writes per-file instead of per-chunk
jphein Apr 10, 2026
86eadc7
fix: add 73 technical terms to entity detector STOPWORDS
jphein Apr 10, 2026
f0856ca
feat: add similarity threshold filtering to search
jphein Apr 10, 2026
8aa33af
feat: hooks save to palace via MCP tools + auto-ingest transcripts
jphein Apr 10, 2026
fccb705
docs: add CLAUDE.md for project context
jphein Apr 10, 2026
5cd14bd
feat: concurrent mining with ThreadPoolExecutor + improved room routing
jphein Apr 10, 2026
77ebae7
feat: add mempalace export command for markdown palace backup
jphein Apr 10, 2026
4406c58
feat: add get/list/update drawer MCP tools + WAL chmod fix + metadata…
jphein Apr 10, 2026
d63ffd4
fix: configurable chunks, Layer1 scan cap, search filter dedup
jphein Apr 10, 2026
4a12748
fix: chunk_text tests, KG direction default, plugin version sync
jphein Apr 10, 2026
83c50ac
fix: PR review feedback — error handling, streaming export, L2 docs
jphein Apr 10, 2026
8f565c7
fix: address remaining PR review feedback (16 items)
jphein Apr 10, 2026
8bd289a
fix: use venv Python in hook scripts for cross-project compatibility
jphein Apr 10, 2026
d16ac4b
fix: portable Python resolution in hook scripts
jphein Apr 10, 2026
ad82c2d
test: add MCP tool tests for get/list/update_drawer
jphein Apr 10, 2026
d8c423b
docs: update expected test count to 573
jphein Apr 10, 2026
6dc8891
refactor: extract _MAX_RESULTS constant for search/list limit cap
jphein Apr 10, 2026
2da4a65
docs: update expected test count to 573
jphein Apr 10, 2026
0259154
feat: silent stop hook — save directly via Python API instead of bloc…
jphein Apr 10, 2026
1efa3ba
feat: configurable hook settings via MCP tool + config
jphein Apr 10, 2026
e9e06c8
fix: use short block reason for terminal visibility instead of stderr
jphein Apr 10, 2026
5ebfcd4
fix: make silent stop hook fully silent — no block, no error label
jphein Apr 10, 2026
930b6d8
feat: checkpoint ack MCP tool for minimal terminal confirmation
jphein Apr 10, 2026
995aed3
fix: fully silent stop hook — no block, no error label
jphein Apr 10, 2026
2209484
feat: systemMessage notification for stop hook checkpoints
jphein Apr 10, 2026
363ef37
fix: advance save marker only after successful checkpoint
jphein Apr 10, 2026
094677b
feat: palace-themed notification with conversation themes
jphein Apr 10, 2026
362a8e1
fix: address PR review feedback — rename, tests, docs
jphein Apr 10, 2026
44545bd
fix: harden MCP server from GPT 5.4 Pro review
jphein Apr 10, 2026
fd0b73d
fix: resolve venv python for background ingest subprocesses
jphein Apr 10, 2026
98e309d
merge: resolve upstream/main conflicts
jphein Apr 10, 2026
8020bdd
fix: cache invalidation in add/delete drawer + doc comments
jphein Apr 10, 2026
8ed7987
fix: address Copilot review — env var override, similarity clamp, utf…
jphein Apr 10, 2026
9e64fe0
feat: junk file filter, purge command, status pagination fix
jphein Apr 10, 2026
1ab6b60
fix: repair command nukes palace dir, MCP server detects db replacement
jphein Apr 10, 2026
f20bdb1
fix: upstream bug fixes — emotion regex, unicode checkmark, KG path, …
jphein Apr 10, 2026
3dd85b6
fix: cherry-pick upstream bug fixes — cosine distance, WAL rotation, …
jphein Apr 10, 2026
173ace8
fix: purge rebuilds index instead of in-place delete, inode comment
jphein Apr 10, 2026
fe5cd56
feat: add --version flag to CLI (from upstream PR #559)
jphein Apr 11, 2026
d4eee82
docs: design spec for tool output capture in conversation mining
jphein Apr 11, 2026
b7d2bc5
docs: implementation plan for tool output mining
jphein Apr 11, 2026
374da40
feat: add _format_tool_use for Claude Code JSONL tool blocks
jphein Apr 11, 2026
9775dd1
feat: add _format_tool_result with per-tool strategies
jphein Apr 11, 2026
66f8195
feat: wire tool_use/tool_result into Claude Code JSONL normalization
jphein Apr 11, 2026
321e77f
docs: add file handle and idempotency comments per review
jphein Apr 11, 2026
b9e2a09
fix: dry-run room=None crash (#586), precompact hook sanitization (#589)
jphein Apr 11, 2026
70dc3df
feat: upgrade chromadb pin from 0.6.x to >=1.5.4 (#581)
jphein Apr 11, 2026
17518c3
feat: hooks auto-mine transcript for tool output capture
jphein Apr 11, 2026
bddc087
docs: update all docs for tool output mining, hook auto-mine, chromad…
jphein Apr 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .claude-plugin/hooks/mempal-precompact-hook.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
#!/bin/bash
# MemPalace PreCompact Hook — thin wrapper calling Python CLI
# All logic lives in mempalace.hooks_cli for cross-harness extensibility
#
# Python resolution order:
# 1. MEMPALACE_PYTHON env var (user override)
# 2. Plugin root's venv (development installs)
# 3. System python3 (pip install --user / pipx)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PLUGIN_ROOT="$(dirname "$SCRIPT_DIR")"

if [ -n "$MEMPALACE_PYTHON" ] && [ -x "$MEMPALACE_PYTHON" ]; then
PYTHON="$MEMPALACE_PYTHON"
elif [ -x "$PLUGIN_ROOT/venv/bin/python3" ]; then
PYTHON="$PLUGIN_ROOT/venv/bin/python3"
else
PYTHON="python3"
fi
INPUT=$(cat)
echo "$INPUT" | python3 -m mempalace hook run --hook precompact --harness claude-code
echo "$INPUT" | "$PYTHON" -m mempalace hook run --hook precompact --harness claude-code
17 changes: 16 additions & 1 deletion .claude-plugin/hooks/mempal-stop-hook.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
#!/bin/bash
# MemPalace Stop Hook — thin wrapper calling Python CLI
# All logic lives in mempalace.hooks_cli for cross-harness extensibility
#
# Python resolution order:
# 1. MEMPALACE_PYTHON env var (user override)
# 2. Plugin root's venv (development installs)
# 3. System python3 (pip install --user / pipx)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PLUGIN_ROOT="$(dirname "$SCRIPT_DIR")"

if [ -n "$MEMPALACE_PYTHON" ] && [ -x "$MEMPALACE_PYTHON" ]; then
PYTHON="$MEMPALACE_PYTHON"
elif [ -x "$PLUGIN_ROOT/venv/bin/python3" ]; then
PYTHON="$PLUGIN_ROOT/venv/bin/python3"
else
PYTHON="python3"
fi
INPUT=$(cat)
echo "$INPUT" | python3 -m mempalace hook run --hook stop --harness claude-code
echo "$INPUT" | "$PYTHON" -m mempalace hook run --hook stop --harness claude-code
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mempalace",
"version": "3.0.14",
"version": "3.1.0",
"description": "Give your AI a memory — mine projects and conversations into a searchable palace. 19 MCP tools, auto-save hooks, and guided setup.",
"author": {
"name": "milla-jovovich"
Expand Down
2 changes: 1 addition & 1 deletion .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mempalace",
"version": "3.0.14",
"version": "3.1.0",
"description": "Give your AI a memory — mine projects and conversations into a searchable palace. 19 MCP tools, auto-save hooks, and guided setup.",
"author": {
"name": "milla-jovovich"
Expand Down
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,5 @@ Knowledge Graph:
- **Modifying mining**: `mempalace/miner.py` (project files) or `mempalace/convo_miner.py` (transcripts)
- **Input validation**: `mempalace/config.py` — `sanitize_name()` / `sanitize_content()`
- **Tests**: mirror source structure in `tests/test_<module>.py`
- **Changing transcript normalization**: `mempalace/normalize.py` — format detection, tool_use/tool_result extraction
- **Hook auto-mining**: `hooks/mempal_save_hook.sh` and `hooks/mempal_precompact_hook.sh` — inline Python for transcript mining
62 changes: 62 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# CLAUDE.md — memorypalace

## What This Is

JP's fork of [milla-jovovich/mempalace](https://github.com/milla-jovovich/mempalace) — a local AI memory system using ChromaDB for verbatim storage and semantic search.

- **Fork**: `jphein/mempalace` (origin) / `milla-jovovich/mempalace` (upstream)
- **Version**: 3.1.0 + local fixes
- **Python**: venv at `./venv/`, editable install with dev deps
- **Palace data**: `~/.mempalace/palace` (ChromaDB) + `~/.mempalace/config.json`

## Key Files

- `~/Projects/mempalace.yaml` — **do not delete**. Mining config with wing/room definitions. Regenerate with `mempalace init ~/Projects --yes` if lost.
- `~/.mempalace/config.json` — topic wings and hall keywords, customized for JP's domains (infrastructure, development, tools, creative, projects, system).
- `~/.mempalace/palace/` — ChromaDB vector store. The actual data.
- `~/.mempalace/hook_state/` — stop hook session tracking.

## Development

```bash
source venv/bin/activate
python -m pytest tests/ -x -q # run tests (648 expected)
mempalace status # check palace state
mempalace search "query" # test search
python -m mempalace.mcp_server # run MCP server standalone
```

Ruff for linting (`ruff check`), line length 100, target Python 3.9.

## Fork Changes (ahead of upstream)

1. **fix: epsilon mtime comparison** — `palace.py` uses `abs() < 0.01` instead of `==` for float mtime dedup
2. **feat: bulk_check_mined()** — paginated pre-fetch of all source_file/mtime pairs
3. **fix: MCP server** — search limit capped [1,100], status/taxonomy tools paginated past 10K, duplicate cache decls removed
4. **perf: batch ChromaDB writes** — one upsert per file instead of per chunk in both miners
5. **fix: entity detector STOPWORDS** — 73 technical terms added (Handler, Node, Service, etc.)
6. **feat: similarity threshold** — `max_distance` parameter in search (renamed from `min_similarity`), default 1.5 L2 distance in MCP
7. **feat: hooks_cli** — stop hook saves directly via Python API with systemMessage notification, precompact blocks for AI-driven save, auto-ingest transcripts
8. **feat: --version flag** — CLI supports `mempalace --version` (from upstream PR #559 pattern)
9. **feat: tool output mining** — normalize.py captures tool_use/tool_result blocks from Claude Code JSONL with per-tool formatting strategies (Bash head+tail, Read/Edit/Write path-only, Grep/Glob capped)
10. **fix: dry-run room=None crash** — miner.py handles None room from unreadable files (#586)
11. **fix: precompact hook SESSION_ID sanitization** — applies same safe() regex as save hook (#589)
12. **feat: chromadb >=1.5.4** — upgraded from 0.6.x pin, auto-migrates existing databases (#581)
13. **feat: hooks auto-mine transcript** — both hooks now auto-mine JSONL transcript into palace (captures raw tool output), updated reason messages to request verbatim tool output, MP_PYTHON auto-detection

## Upstream PRs

- milla-jovovich/mempalace#483 — mtime dedup fix
- milla-jovovich/mempalace#484 — search limit + pagination + cache fix
- milla-jovovich/mempalace#562 — tool output mining, bug fixes, chromadb upgrade (18 upstream issues addressed)

## Integration

- **Claude Code plugin**: installed at user scope via marketplace
- **MCP server**: global user scope — available in all projects
- **Stop hook**: fires every 15 messages, auto-mines transcript for tool output, blocks AI to save with verbatim tool output instructions
- **PreCompact hook**: emergency save before context compaction, auto-mines transcript, finds transcript by session_id fallback

## Testing

Always run `python -m pytest tests/ -x -q` after changes. 648 tests expected to pass. Benchmark and stress tests are excluded by default (use `-m benchmark` or `-m stress` to include).
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -512,9 +512,9 @@ The AI learns AAAK and the memory protocol automatically from the `mempalace_sta

Two hooks for Claude Code that automatically save memories during work:

**Save Hook** — every 15 messages, triggers a structured save. Topics, decisions, quotes, code changes. Also regenerates the critical facts layer.
**Save Hook** — Every 15 messages, auto-mines the JSONL transcript directly into the palace (capturing raw tool output — Bash results, search findings, build errors), then triggers a structured AI save with explicit instructions to preserve tool output verbatim.

**PreCompact Hook** — fires before context compression. Emergency save before the window shrinks.
**PreCompact Hook** — Fires before context compression. Auto-mines the transcript, then forces emergency save with verbatim tool output instructions.

```json
{
Expand All @@ -527,6 +527,8 @@ Two hooks for Claude Code that automatically save memories during work:

**Optional auto-ingest:** Set the `MEMPAL_DIR` environment variable to a directory path and the hooks will automatically run `mempalace mine` on that directory during each save trigger (background on stop, synchronous on precompact).

Set `MEMPAL_PYTHON` to your Python interpreter with mempalace + chromadb installed. Auto-detects repo venv if not set.

---

## Benchmarks
Expand Down Expand Up @@ -632,7 +634,7 @@ Plain text. Becomes Layer 0 — loaded every session.
|------|------|
| `cli.py` | CLI entry point |
| `config.py` | Configuration loading and defaults |
| `normalize.py` | Converts 5 chat formats to standard transcript |
| `normalize.py` | Converts 6 chat formats to standard transcript, captures tool_use/tool_result blocks from Claude Code JSONL |
| `mcp_server.py` | MCP server — 19 tools, AAAK auto-teach, memory protocol |
| `miner.py` | Project file ingest |
| `convo_miner.py` | Conversation ingest — chunks by exchange pair |
Expand All @@ -645,8 +647,8 @@ Plain text. Becomes Layer 0 — loaded every session.
| `entity_registry.py` | Entity code registry |
| `entity_detector.py` | Auto-detect people and projects from content |
| `split_mega_files.py` | Split concatenated transcripts into per-session files |
| `hooks/mempal_save_hook.sh` | Auto-save every N messages |
| `hooks/mempal_precompact_hook.sh` | Emergency save before compaction |
| `hooks/mempal_save_hook.sh` | auto-mine + save every N messages |
| `hooks/mempal_precompact_hook.sh` | auto-mine + emergency save |

---

Expand Down Expand Up @@ -674,23 +676,23 @@ mempalace/
│ └── membench_bench.py ← MemBench runner
├── hooks/ ← Claude Code auto-save hooks
│ ├── README.md ← hook setup guide
│ ├── mempal_save_hook.sh ← save every N messages
│ └── mempal_precompact_hook.sh ← emergency save
│ ├── mempal_save_hook.sh ← auto-mine + save every N messages
│ └── mempal_precompact_hook.sh ← auto-mine + emergency save
├── examples/ ← usage examples
│ ├── basic_mining.py
│ ├── convo_import.py
│ └── mcp_setup.md
├── tests/ ← test suite (README)
├── assets/ ← logo + brand assets
└── pyproject.toml ← package config (v3.0.0)
└── pyproject.toml ← package config (v3.1.0)
```

---

## Requirements

- Python 3.9+
- `chromadb>=0.4.0`
- `chromadb>=1.5.4`
- `pyyaml>=6.0`

No API key. No internet after install. Everything local.
Expand Down
Loading