Skip to content
Agentmart
Submit a tool

machine-move

Live multi-machine sync (the daily driver) OR one-time new-machine setup.

Skill by itgenius-au

IndexedMIT★ 1
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/itgenius-au-machine-move

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Live multi-machine sync (the daily driver) OR one-time new-machine setup. SYNC pushes all git state online, pulls the other machine's work, prunes merged branches, keeps tooling current and makes local-only data durable; its dry run is also the pre-flight audit before you leave a machine. SETUP bootstraps a fresh machine. Triggers on: machine move, move computer, switch machine, new computer, setup machine, receiving machine, sync machine, sync everything online, synchronise machines, push everything up, pre-flight check, sync check, portability check

Use cases: data, security

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/machine-move

What's inside

Skill name
machine-move
Description
Live multi-machine sync (the daily driver) OR one-time new-machine setup. SYNC pushes all git state online, pulls the other machine's work, prunes merged branches, keeps tooling current and makes local-only data durable; its dry run is also the pre-flight audit before you leave a machine. SETUP bootstraps a fresh machine. Triggers on: machine move, move computer, switch machine, new computer, setup machine, receiving machine, sync machine, sync everything online, synchronise machines, push everything up, pre-flight check, sync check, portability check
License
MIT
Instructions
456 lines in SKILL.md · view on GitHub

Before installing

  • Instructions read files in your home folder (~/.ssh, ~/.aws…)

Agent Skills spec issues

  • files: referenced but missing: scripts/repos.txt

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Machine Move

Two modes:

1. **SYNC** (live multi-machine sync) - the daily driver. Run it on ANY machine you work on, as often as you like, back and forth. It pushes everything online (main checkout, child repos, worktree branches, dirty-worktree work-in-progress commits) and pulls anything another machine pushed, **without closing anything out**. Then it brings tooling up to date, prunes fully-merged branches, and makes local-only data durable. The SYNC dry run is also the **pre-flight audit**: run it before you leave a machine.
2. **SETUP** (new machine bootstrap) - run ONCE on a new machine after cloning your main repo. Runs your setup scripts, pulls all repos, authenticates, verifies the environment. A fresh machine has nothing for SYNC to act on until SETUP has run.

There is no separate "sending" mode. Leaving a machine is just a final SYNC: it gets every branch and every dirty worktree online, and the local-data step makes files that never enter git durable.

## Mode detection

Ask if ambiguous; otherwise infer:
- "new computer", "just set up", "set up this machine", "receiving", "just opened here", "clone everything" -> **SETUP**
- "sync", "sync this machine", "sync everything online", "push everything up", "pre-flight", "before I leave this machine", "switching computers", "portability check" -> **SYNC**
- "machine move" with no qualifier -> ask

## Configure once: your repo set

Both modes loop over the same set of repos: the main ("parent") repo plus any child repos you keep beside or inside it. Keep that list in ONE place, a plain file with one directory per line (comments start with `#`), for example `scripts/repos.txt` in your parent repo:

```
# directory (relative to the parent repo)
child-project-1
child-project-2
```

Read it with a loop that is safe in both bash and zsh (a literal `for d in $REPOS` string does not word-split in zsh and silently iterates once):

```bash
BASE="$(git rev-parse --show-toplevel)"
REPOS_FILE="$BASE/scripts/repos.txt"          # CONFIGURE
# parent + children
{ printf '.\n'; grep -vE '^[[:space:]]*(#|$)' "$REPOS_FILE"; } | while IFS= read -r dir; do
  echo "=== $dir ==="
  # ... per-repo commands, run as: git -C "$BASE/$dir" ...
done
```

Everything below that says "per repo" means this loop.

---

# SYNC MODE - Live Multi-Machine Sync

A SYNC run has three parts: **repos** (Steps 0-4), **tooling and hygiene** (Steps 5-8), and **local data** (Step 9). A sync is not finished when the repos converge; it is finished when the machine is also on current tools and its local-only data is durable.

## Why it exists

Anything that wip-commits for you (an auto-commit hook, an editor) but never pushes silently accumulates unpushed commits on `main`, child repos and worktree branches. Files you generate or download during a session sit only on this disk. SYNC gets all of it online and pulls the other machine's work back.

## Safety contract (non-negotiable)

- **Append-only.** Push branches that are ahead. Never `--force`, never squash, never soft-reset. (Every historical force-push traced to squashing commits that were already pushed.)
- **Behind -> `git pull --ff-only`** (no merge commits).
- **Diverged -> tag a backup first** (`git tag sync-backup/<branch>-<stamp>`), then rebase ONLY if the diverged commits touch disjoint files. On file overlap, **surface it for a human**. Never auto-resolve "drop local / take remote".
- **Worktrees: never touch a dirty or live worktree, and never do anything but a fast-forward.** Push the branch ref; never merge-to-main, remove, switch, force, or reconcile content. A dormant dirty worktree may get a `wip` commit so the work is captured, unless a live session owns it or a rebase/merge/cherry-pick/bisect is mid-flight (`.git/rebase-merge`, `rebase-apply`, `MERGE_HEAD`, `CHERRY_PICK_HEAD`, `BISECT_LOG`, `sequencer/`). A clean, dormant worktree that is purely behind **its own** remote branch may be fast-forwarded onto `origin/<its-branch>` only.
- **"Live" means any of:** a Claude Code transcript for that path touched in the last 10 minutes, a process whose cwd is inside it, or a changed file (staged, unstaged or untracked, not ignored) edited in the last 30 minutes. If a liveness check itself errors, treat the worktree as live.
- **Per-repo resilient.** One repo's failure never aborts the sweep. Collect failures and report them.
- **Preserve before reconcile.** The backup tag exists before any rebase.

## Step 0: Setup readiness (always first, read-only)

SYNC assumes SETUP has run once on this machine (or, on a shared host, this account). On a machine that was never set up, a sweep would "succeed" on a half-empty environment: no child repos, no settings, no hooks. Check first, and stop if SETUP never ran.

```bash
miss=0; warn=0
[ -f ~/.claude/machine-setup-done ] || { echo "BLOCK: no setup marker (~/.claude/machine-setup-done)"; miss=1; }
[ -f ~/.claude/settings.json ]      || { echo "BLOCK: ~/.claude/settings.json missing"; miss=1; }
# At least one child repo from your repos file must be cloned (the parent alone is not a set-up machine).
cloned=0; total=0
while IFS= read -r dir; do
  total=$((total+1)); { [ -d "$BASE/$dir/.git" ] || [ -f "$BASE/$dir/.git" ]; } && cloned=$((cloned+1))
done < <(grep -vE '^[[:space:]]*(#|$)' "$REPOS_FILE")
[ "$total" -gt 0 ] && [ "$cloned" -eq 0 ] && { echo "BLOCK: none of the $total child repos is cloned"; miss=1; }
[ "$cloned" -lt "$total" ] && { echo "WARN: $((total-cloned)) of $total child repos not cloned (a headless machine may skip some on purpose)"; warn=1; }
# Add your own BLOCK checks here: deployed hooks, the plugin manifest, a Claude Code login, a cloud login.
[ "$miss" -eq 0 ] && echo "READY (warnings: $warn)" || echo "SETUP NEEDED"
```

- **BLOCK** (`SETUP NEEDED`): stop the sync, tell the owner, and switch to SETUP mode. Do not work around it by skipping the check. A BLOCK that is only "the plugin manifest gained a plugin" (often arriving with a pull) is not a missing SETUP: install the missing plugins (install-only, never a clean or uninstall), then re-run the check.
- **WARN**: report it and continue. A repo skipped on purpose stays a warning, and an expired cloud login is reported so it is renewed before Step 9.

Running this loop from a worktree session needs the main checkout as `BASE` (see "Running SYNC from a worktree session").

## Step 1: Dry run (always first, read-only)

Fetch every repo and report what a sync WOULD do. Nothing changes.

```bash
{ printf '.\n'; grep -vE '^[[:space:]]*(#|$)' "$REPOS_FILE"; } | while IFS= read -r dir; do
  r="$BASE/$dir"
  [ -d "$r/.git" ] || [ -f "$r/.git" ] || { echo "=== $dir === MISSING (not cloned)"; continue; }
  echo "=== $dir ==="
  git -C "$r" fetch --all --prune --quiet 2>&1 || echo "  FAIL: fetch"
  git -C "$r" status -sb | head -1                          # branch + ahead/behind
  git -C "$r" status -s | head -20                          # uncommitted
  git -C "$r" stash list                                    # stashed work
  git -C "$r" for-each-ref --format='%(refname:short) %(upstream:short) %(upstream:track)' refs/heads \
    | awk '$2=="" {print "  no upstream: " $1} $3!="" {print "  " $0}'   # local-only / ahead / behind branches
  git -C "$r" log --branches --not --remotes --oneline | head -20   # unpushed commits on ANY branch
  git -C "$r" worktree list                                 # worktrees to check for dirt/liveness
done
```

Present it as a table, one row per repo (and per worktree): uncommitted, stashes, local-only branches, unpushed, behind. Classify each branch: `IN-SYNC`, `WOULD-PUSH`, `WOULD-FF-PULL`, `WOULD-REBASE` (disjoint divergence), `SURFACE` (overlapping divergence, needs a human). For each worktree: `WT-WOULD-PUSH`, `WT-WOULD-COMMIT` (dormant dirty), `WT-BEHIND` (clean, behind its own remote), `WT-SKIP` (detached HEAD or mid-sequencer), `WT-SKIP-DIRTY` (live, leave alone). Flag every non-clean row.

If you only came for the pre-flight audit, stop here and report: "Safe to leave" (all clean and pushed) or the list of problems with the fix for each.

## Step 2: One blanket approval, then execute

Ask once: "push main + children + worktree branches, ff-pull where behind, rebase only disjoint divergences (backup-tagged first), wip-commit dormant dirty worktrees; nothing destructive". Then, per repo:

```bash
git -C "$r" push origin <branch>            # branches that are ahead (use -u for a branch with no upstream)
git -C "$r" pull --ff-only                  # current branch, when behind
# diverged, disjoint files only:
git -C "$r" tag "sync-backup/<branch>-$(date +%Y%m%d-%H%M)" <branch>
git -C "$r" rebase origin/<branch>
```

From itgenius-au/skills-library, MIT.

More from itgenius-au/skills-library

Signals

Stars
1
Forks
0
Open issues
1
Last commit (this folder)
Oct 22, 2026 (7 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from itgenius-au

Cite this page

machine-move skill. Agent Mart. https://agentmart.dev/skills/itgenius-au-machine-move (last updated 2026-10-24)