--- title: "Memory Compiler — Migrating Between Mac Users" aliases: [memory-compiler-migration, cc-memory-migration, claude-code-path-migration] tags: [memory-compiler, claude-code, hooks, macos, migration, knowledge-base] sources: - "daily/2026-04-24.md" - "daily/2026-04-22.md" created: 2026-04-24 updated: 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_ROOT` explicitly set as an environment variable — if missing, the obsidian session-start script silently produces empty context - **`cc-collector.py` has a folder name bug**: `_root_prefix()` derives the project identifier using underscores, but the session storage folder name uses hyphens (e.g., `ai-leed` not `ai_leed`) — the fix is to ensure the prefix conversion maps `_` → `-` - **`wiki/reports/_index.md`** must 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 wiki - **`projects-overview` article 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 | None` union types) silently fail when invoked with `/usr/bin/python3`; replace with `/opt/homebrew/bin/python3` in all hook commands - **Fish Fisher plugins** require fresh reinstall after conf.d files are copied — delete manually copied conf.d files and run `fisher update` to regenerate them cleanly - **`time_tracker.py`** had two bugs after migration: missing `xlsxwriter` package and a hardcoded `/Volumes/SSD/Projects/Oliver` path; fix uses `OLIVER_ROOT` auto-detection supporting both old SSD and new `~/Documents/Projects/Oliver` prefixes - 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`: ```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()`:** ```python 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`: ```markdown # 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 | |--------|--------|-----------| ``` 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: ```bash # Fetch a specific file scp aimpress@:/Users/aimpress/.claude/settings.json /tmp/old-settings.json # Or rsync a directory rsync -avz aimpress@:/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: ```bash # 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 `/schedule` skill 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 | None` syntax - [[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