155 lines
8.3 KiB
Markdown
155 lines
8.3 KiB
Markdown
---
|
||
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 |
|
||
|--------|--------|-----------|
|
||
|
||
<!-- 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:
|
||
|
||
```bash
|
||
# 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:
|
||
|
||
```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
|