8.3 KiB
| title | aliases | tags | sources | created | updated | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Memory Compiler — Migrating Between Mac Users |
|
|
|
2026-04-24 | 2026-04-25 |
Memory Compiler — Migrating Between Mac Users
Migrating the Claude Code memory-compiler system from one Mac user account to another (or between machines with different usernames) requires several manual fixes that are not obvious from the README. The hooks, cc-collector.py, and the wiki structure all have hardcoded or derived path assumptions that break on a new user path. Missing any of these produces silent failures — sessions appear to flush correctly but no data reaches the knowledge base.
Key Points
- All 3 hooks (SessionStart, PreCompact, SessionEnd) must have
PROJECTS_ROOTexplicitly set as an environment variable — if missing, the obsidian session-start script silently produces empty context cc-collector.pyhas a folder name bug:_root_prefix()derives the project identifier using underscores, but the session storage folder name uses hyphens (e.g.,ai-leednotai_leed) — the fix is to ensure the prefix conversion maps_→-wiki/reports/_index.mdmust exist for the reports topic to appear in the master index — it is not auto-created and must be created manually when setting up a fresh wikiprojects-overviewarticle count must be updated in the master index after migration (was 36 on old Mac; 37 on new Mac after project was added)- macOS system
python3= 3.9 — hooks that use Python 3.10+ syntax (Path | Noneunion types) silently fail when invoked with/usr/bin/python3; replace with/opt/homebrew/bin/python3in all hook commands - Fish Fisher plugins require fresh reinstall after conf.d files are copied — delete manually copied conf.d files and run
fisher updateto regenerate them cleanly time_tracker.pyhad two bugs after migration: missingxlsxwriterpackage and a hardcoded/Volumes/SSD/Projects/Oliverpath; fix usesOLIVER_ROOTauto-detection supporting both old SSD and new~/Documents/Projects/Oliverprefixes- The old Mac's files are accessible via SSH if needed — no need to manually recreate plugin caches or config files
Details
Hook Environment Variables (PROJECTS_ROOT)
The obsidian hooks (obsidian-session-start.py, obsidian-pre-compact.py, obsidian-stop.py) read a PROJECTS_ROOT environment variable to find project directories. On the old Mac this was set in the hook command line; when migrating, it must be re-added to the global ~/.claude/settings.json for each hook.
The format in ~/.claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"hooks": [{
"type": "command",
"command": "PROJECTS_ROOT=/Users/ai_leed/Projects python3 ~/.claude/obsidian-session-start.py ...",
"statusMessage": "Loading Obsidian context..."
}]
}
]
}
}
If PROJECTS_ROOT is missing, the hook runs but finds no projects — additionalContext is empty. The session proceeds without any Obsidian note context injected, and no error appears. This is the silent failure mode.
cc-collector.py Folder Name Bug
The cc-collector.py script (part of the Claude Code dashboard collector) uses _root_prefix() to derive a project identifier from the project directory path. The function was converting the macOS username portion of the path to an identifier using underscores: /Users/ai_leed/... → ai_leed_....
However, Claude Code stores session data in folders named with hyphens: ai-leed not ai_leed. The mismatch meant cc-collector.py was looking for session files in a folder that didn't exist.
Fix applied to _root_prefix():
def _root_prefix(path: str) -> str:
# Convert path separators to hyphens, not underscores
# Folder names use hyphens: /Users/ai_leed -> ai-leed (not ai_leed)
parts = path.strip("/").split("/")
return "-".join(parts).replace("_", "-")
The general pattern: whenever deriving a folder name from a user path, use hyphens throughout.
Creating wiki/reports/_index.md
The reports section of the master index (| [[wiki/reports/_index\|reports/]] | ... | 0 |) requires the file to exist. A fresh wiki setup does not create it automatically.
Minimal file to create at wiki/reports/_index.md:
# Reports — Topic Index
> Weekly and monthly knowledge base summaries generated by report-generator.py.
> Compiled automatically via launchd on Mondays (weekly) and the 1st of each month (monthly).
| Report | Period | Generated |
|--------|--------|-----------|
<!-- Reports added automatically by report-generator.py -->
Without this file, links in the master index are broken wikilinks that Obsidian highlights in red.
Migration Checklist
Complete checklist when migrating the memory-compiler to a new Mac user:
[ ] 1. Clone/copy memory-compiler repo to ~/.claude/memory-compiler
[ ] 2. Run: cd ~/.claude/memory-compiler && uv sync
[ ] 3. Update all hook commands in ~/.claude/settings.json with new username paths
[ ] 4. Add PROJECTS_ROOT=... env var to each obsidian hook command
[ ] 5. Replace all bare `python3` in hook commands with /opt/homebrew/bin/python3
[ ] 6. Verify cc-collector.py _root_prefix() uses hyphens not underscores
[ ] 7. Create wiki/reports/_index.md if missing
[ ] 8. Update projects-overview article count in _master-index.md if it changed
[ ] 9. rsync Fish config, then delete conf.d/*.fish and run `fisher update`
[ ] 10. Run a manual compile to verify pipeline: uv run python scripts/compile.py --dry-run
[ ] 11. Set up launchd jobs for weekly/monthly reports (if /schedule skill unavailable)
[ ] 12. Verify SessionStart hook fires: open a new Claude Code session, check additionalContext
Identifying Old Mac Files via SSH
If config files, plugin caches, or other assets exist on the old Mac under /Users/aimpress/ and are needed, they can be fetched via SSH:
# Fetch a specific file
scp aimpress@<old-mac-ip>:/Users/aimpress/.claude/settings.json /tmp/old-settings.json
# Or rsync a directory
rsync -avz aimpress@<old-mac-ip>:/Users/aimpress/.claude/plugins/ ~/.claude/plugins/
There is no need to recreate plugin caches manually — they rebuild on first use.
Verifying the Pipeline After Migration
After completing the migration checklist, verify each layer:
# 1. Test hooks fire (open Claude Code, look for "Loading knowledge context..." status)
# 2. Test flush works
cd ~/.claude/memory-compiler
echo "test session" > /tmp/test-flush.md
uv run python scripts/flush.py /tmp/test-flush.md
# 3. Test compile works
uv run python scripts/compile.py --dry-run
# 4. Check logs
tail -20 scripts/flush.log
tail -20 scripts/compile.log
A successful flush appends a FLUSH_OK line or bullet points to daily/YYYY-MM-DD.md. A failed flush appends FLUSH_ERROR: Exception: Command failed with exit code 1.
Related Concepts
- wiki/concepts/claude-code-schedule-skill-account-type — the
/scheduleskill limitation discovered during this migration session; launchd used as fallback - wiki/concepts/macos-python-version-hooks — system Python 3.9 vs Homebrew Python issue that breaks hooks using
Path | Nonesyntax - wiki/concepts/fish-fisher-conf-d-conflict — Fisher plugin conflict caused by manually copying conf.d files during migration
- wiki/claude-code/overview — Claude Code hook system overview including SessionStart, PreCompact, SessionEnd
- wiki/obsidian-rag/_index — the Karpathy LLM wiki method that the memory-compiler implements
Sources
- daily/2026-04-24.md — Mac migration session (/Users/aimpress/ → /Users/ai_leed/): 3 hooks missing PROJECTS_ROOT env var (all fixed); cc-collector.py _root_prefix() underscore→hyphen bug found and fixed; wiki/reports/_index.md created; projects-overview count updated 36→37; 6 daily logs (Apr 19–24) compiled manually after migration
- daily/2026-04-22.md — Continuing migration on ai_leed@192.168.1.44: Fisher showed 2/9 plugins (conf.d conflict fixed); rsync transferred 45 projects / 2.6 GB; time_tracker.py fixed (xlsxwriter + hardcoded path); hooks silently failing due to system Python 3.9; all hooks updated to use /opt/homebrew/bin/python3