plugins/claude-code-hermit/skills/migrate/SKILL.md
Audit a hermit-backed repo for safe migration to another machine. Classifies files, generates a migration manifest, and produces a verification checklist. Git-first, conservative by default.
npx skillsauth add gtapps/claude-code-hermit migrateInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Audit the current repo for safe migration to another machine. Produce a classification of files to migrate, a manifest, bootstrap requirements, and a verification checklist.
Git is the source of truth. Migration should be minimal. This skill is read-only — it does not modify files unless you explicitly ask.
.claude/settings.json — project-scoped (committed). Tracked in git. Migrates with git clone..claude/settings.local.json — machine/user-scoped (gitignored). Contains task list ID (always) and hook permissions + deny patterns (when plugin was installed at local or user scope). Must be recreated on destination — never migrated by git clone. Check .claude-code-hermit/state/hatch-options.json "target" field: if "local", this file contains hermit's hook permissions and deny patterns; the operator must re-run /hatch or /hermit-evolve on the destination to restore them..claude.local/ — machine/user-scoped (channel state dirs, local overrides). Needs recreation on destination. Never migrated..claude/settings.json migrates with git clone — never flag it for manual migration or recreation.claude/settings.local.json does NOT migrate with git clone — flag for recreation on destination.claude.local/ must be recreated on destination — never migratedCheck if .claude-code-hermit/ exists. If it doesn't, note in the summary that this repo hasn't been hatched — the hermit state assessment section will be N/A, but the rest of the audit (Git hygiene, ignored files, bootstrap) still applies.
Read the following files if they exist:
.claude-code-hermit/config.json.claude-code-hermit/OPERATOR.md.claude-code-hermit/HEARTBEAT.md.claude-code-hermit/IDLE-TASKS.md.gitignoreRun git status and git ls-files to check:
.gitignore rules (patterns that should be excluded but aren't)Note: findings here do not block the migration audit, but they affect the migration risk level.
Batch these three git commands — results are reused in step 4:
git ls-files # tracked files
git ls-files --others --exclude-standard # untracked, not ignored
git ls-files --others --ignored --exclude-standard # ignored files (for step 4)
Scan for unprotected credentials across tracked and untracked-but-not-ignored files:
*.pem, *.key, id_rsa, id_ed25519, *.p12, *.pfx, *credentials*, *secret*, *token*, *auth*.json.claude.local/ and any files inside it (channel tokens, access.json, .env files inside subdirs)git ls-files | xargs grep -l "API_KEY=\|TOKEN=\|SECRET=\|PASSWORD=\|DISCORD_TOKEN=\|TELEGRAM_TOKEN=" to find tracked files with inline credentials. If step 2 already surfaced matches for these patterns, include them here and skip re-scanning those paths.For any unprotected credentials found, propose gitignore additions — list the file, explain why it should be gitignored, and provide the exact .gitignore line to add. This is advisory only. Do not write .gitignore automatically.
If nothing is found, state: "No unprotected credentials found."
Use the ignored file list from step 3's batch run. These are the candidates for classification.
Skip .claude-code-hermit/ entries — those are handled in step 6.
Sort each remaining ignored file into one of three buckets:
MUST_MIGRATE — portable, required for operation on the destination, not regenerable DO_NOT_MIGRATE — runtime state, caches, build artifacts, machine-local config, secrets, ephemeral files REVIEW_MANUALLY — ambiguous portability: .env variants without clear template policy, local databases, repo-local memory files whose portability is unclear
Apply classification heuristics (see below). For each file include a one-line reason.
Classify each .claude-code-hermit/ artifact using the defaults table. For each artifact present, state the classification and why.
For config.json specifically, provide field-level analysis:
agent_name, language, escalation, sign_off, idle_behavior, idle_budget, auto_session, ask_budget, chrome, heartbeat, compact, env (most entries), routines, scheduled_checks, dockertimezone, channels.*.dm_channel_id, tmux_session_name, permission_mode — see docs/config-reference.md for any fields added since this list was writtenchannels.*.state_dir: If the value is a relative path (e.g. .claude.local/channels/discord), it is portable and can be copied as-is. If it is an absolute path (legacy), treat it as machine-specific and update it on the destination.hatch and manually port identity/behavior settingsInspect setup/context docs if present: README, Makefile, package.json, requirements.txt, pyproject.toml, Cargo.toml, go.mod, Dockerfile, docker-compose.yml, .env.example. Do not force a fixed list — read what exists and is relevant to bootstrap.
Based on these docs, identify what the destination machine must have:
Flag anything that is assumed but not documented.
.claude.local/ is machine/user-scoped. Never migrate it. Using config.json read in step 1, identify what must be recreated on the destination:
state_dir path from config.json)Note: .claude/ (project-scoped settings, permissions) migrates with git clone — no recreation needed.
Produce the report in the format below.
## 1. Summary & Verdict
[One paragraph: is this migration straightforward or risky? What does it require beyond `git clone`?]
## 2. Git Hygiene Findings
[List of tracked files that shouldn't be, missing gitignore rules, secrets exposure. "None found" if clean.]
## 3. Credential Scan
### Unprotected credentials found
- path/to/file — reason and proposed .gitignore line
### Already protected
- path/to/file — already gitignored
(Or: "No unprotected credentials found.")
## 4. File Classification
### MUST_MIGRATE
- path/to/file — reason
### DO_NOT_MIGRATE
- path/to/file — reason
### REVIEW_MANUALLY
- path/to/file — reason and what to decide
## 5. Hermit State Assessment
| Artifact | Classification | Guidance |
|----------|---------------|----------|
| OPERATOR.md | MUST_MIGRATE | human-curated, cannot be regenerated |
| ... | ... | ... |
**config.json field breakdown:**
Portable: [list fields present in this config that are safe to copy]
Machine-specific: [list fields that must be updated on destination]
Recommendation: [copy-then-edit or recreate-from-hatch]
## 6. migration-manifest.txt
[Exact content of the manifest — repo-relative paths, one per line, derived from MUST_MIGRATE classifications above]
## 7. Bootstrap / Recreate-on-Destination Requirements
**Tools required:**
- [tool name] [version if known]
**Environment variables:**
- [VAR_NAME] — [source or description]
**Services:**
- [service name]
**.claude.local/ recreation:**
- Recreate channel state dirs: [list each channel and its state_dir path]
- Re-pair channels after setup
## 8. Migration Steps
1. On source machine: ensure the working tree is clean — commit or stash before proceeding (`git status`)
2. `git push` to ensure remote is current
3. On destination: `git clone <repo-url>`
4. Copy files from manifest:
rsync -av --files-from=migration-manifest.txt /source/path/ user@destination:/dest/path/
(Other transport methods work equally well with the same manifest.)
5. On destination: run `/claude-code-hermit:hatch` to initialize hermit state
- hatch preserves existing OPERATOR.md, config.json, HEARTBEAT.md, IDLE-TASKS.md if present
6. Update machine-specific fields in config.json
7. Recreate .claude.local/ (channel state dirs — see section 7)
8. Run verification checklist
## 9. Verification Checklist
- [ ] `git status` is clean on destination
- [ ] All MUST_MIGRATE files are present and intact
- [ ] config.json machine-specific fields have been updated
- [ ] Hermit session starts without errors
- [ ] Bootstrap requirements are met (tools, env vars, services)
- [ ] .claude.local/ is recreated (channel state dirs re-paired)
- [ ] Run a test session to confirm normal operation
| Artifact | Default | Notes |
|----------|---------|-------|
| OPERATOR.md | usually MUST_MIGRATE | human-curated, not regenerable |
| HEARTBEAT.md | usually MUST_MIGRATE | operator-customized |
| IDLE-TASKS.md | usually MUST_MIGRATE | operator-customized |
| config.json | REVIEW_MANUALLY | portable + machine-specific fields mixed — requires field-level analysis |
| sessions/ | usually DO_NOT_MIGRATE | historical runtime state; operator may choose to archive |
| proposals/ | usually DO_NOT_MIGRATE | historical; operator may choose to archive |
| state/ | DO_NOT_MIGRATE | runtime ephemeral |
| templates/ | DO_NOT_MIGRATE | regenerated by hatch |
| bin/ | DO_NOT_MIGRATE | regenerated by hatch |
| .claude/ | migrates with clone | project-scoped — no action needed |
| .claude.local/ | recreate on destination | machine/user-scoped — never migrate |
The "usually" qualifiers matter. Context overrides defaults.
For files not covered by the defaults above:
Always DO_NOT_MIGRATE: build artifacts, caches, logs, lock files, pid files, temp files, node_modules/, vendor/, editor/OS junk, auth credentials, SSH keys, tokens, session exports, browser data.
REVIEW_MANUALLY when: .env files without a clear template equivalent, SQLite or local database files, hand-maintained local config directories, local seed data, repo-local memory or state files whose portability is unclear.
MUST_MIGRATE only when: the file is genuinely portable (no machine-bound paths or credentials), required for the repo to function on destination, and not regenerable from code or hatch.
/claude-code-hermit:hatch on the destination to handle hermit initialization — it preserves OPERATOR.md, config.json, and operator-customized files during re-init/claude-code-hermit:hermit-evolve after hatch to apply any upgrade stepstools
Presence history & tracker-health report — current home/away state, reliability, recent arrival/departure transitions, and activity patterns for person/device_tracker entities. Use when the operator asks about presence history or when a presence-dependent automation (locks, alarm, vacuum, climate) misbehaves.
development
Evening house brief — end-of-day security check, device status, and energy snapshot. Runs as a daily routine at 22:30 or on demand.
tools
Browse and explain the hermit's Home Assistant automations — list by topic, filter by keyword with plain-language YAML explanations, or sort by last-fired. Read-only. Use when the operator asks "what automations do I have / what does this one do / which haven't fired."
tools
On-demand HA-voice brainstorm — reads entity inventory, automation/script listings, and operator intent to surface at most 2 capability-gap ideas, each gated by proposal-triage before becoming a PROP. Invoke when the operator asks "what automations am I missing?", "any coverage gaps?", or "brainstorm improvements". Never runs autonomously.