obsidian/wiki/concepts/memory-compiler-mac-migration.md
2026-04-26 21:10:46 +01:00

8.3 KiB
Raw Blame History

title aliases tags sources created updated
Memory Compiler — Migrating Between Mac Users
memory-compiler-migration
cc-memory-migration
claude-code-path-migration
memory-compiler
claude-code
hooks
macos
migration
knowledge-base
daily/2026-04-24.md
daily/2026-04-22.md
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_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:

{
  "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.

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 1924) 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