Step 1 of 5
Prepare Git authentication
Use GitHub CLI over HTTPS so the LaunchAgent can authenticate through the macOS Keychain without depending on an interactive SSH agent.
gh auth status || gh auth login
gh config set git_protocol https
gh auth setup-git
git config --global user.name "YOUR_NAME"
git config --global user.email "YOUR_EMAIL"Step 2 of 5
Preserve the local library
Quit Codex, Cursor, and any agent currently reading skills. Move the existing local directory aside, then clone the VPS-backed repository into the canonical ~/.agents path.
backup_dir="$HOME/.agents.backup.$(date +%Y%m%d-%H%M%S)"
if [ -d ~/.agents ]; then mv ~/.agents "$backup_dir"; fi
git clone https://github.com/YOUR_ACCOUNT/code-os-skills.git ~/.agents
echo "Previous local skills: $backup_dir"Step 3 of 5
Install the same worker
Configure the same repository, checkout, and branch in the local Code OS dashboard. Both machines then use the identical audited command and private Git branch. Run it once interactively before scheduling it.
mkdir -p ~/.local/bin
curl -fsSL https://code-os.mlvcdn.com/skills-sync.sh -o ~/.local/bin/code-os-skills-sync
chmod 700 ~/.local/bin/code-os-skills-sync
~/.local/bin/code-os-skills-syncStep 4 of 5
Schedule it with launchd
The LaunchAgent starts after login and runs every two minutes. Logs stay in ~/Library/Logs/CodeOS.
mkdir -p ~/Library/LaunchAgents ~/Library/Logs/CodeOS
cat > ~/Library/LaunchAgents/dev.code-os.skills-sync.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>dev.code-os.skills-sync</string>
<key>ProgramArguments</key><array>
<string>/bin/zsh</string><string>-lc</string>
<string>$HOME/.local/bin/code-os-skills-sync</string>
</array>
<key>RunAtLoad</key><true/>
<key>StartInterval</key><integer>120</integer>
<key>StandardOutPath</key><string>LOCAL_LOG_PATH/code-os-skills-sync.log</string>
<key>StandardErrorPath</key><string>LOCAL_LOG_PATH/code-os-skills-sync.error.log</string>
</dict></plist>
EOF
sed -i '' "s|LOCAL_LOG_PATH|$HOME/Library/Logs/CodeOS|g" ~/Library/LaunchAgents/dev.code-os.skills-sync.plist
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/dev.code-os.skills-sync.plist 2>/dev/null || true
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/dev.code-os.skills-sync.plistStep 5 of 5
Verify both directions
Create a harmless test file on the computer, run a sync, then confirm it arrives on the VPS after the next timer execution.
touch ~/.agents/.sync-check
~/.local/bin/code-os-skills-sync
launchctl kickstart -k gui/$(id -u)/dev.code-os.skills-sync
tail -n 30 ~/Library/Logs/CodeOS/code-os-skills-sync.log
git -C ~/.agents status --short --branchOn the VPS, run systemctl --user start code-os-skills-sync.service, check that .sync-check exists, then remove it and sync once more.
~/.agents is synchronized. Project repositories, Code OS configuration, tokens, and screenshot bypass keys stay machine-local.If Git reports a conflict
The worker stops and will not stage anything else while a rebase, merge, or unresolved file exists. Inspect the files and choose one path:
git -C ~/.agents status
# Keep the rebase and resolve each reported file
git -C ~/.agents add PATH_TO_RESOLVED_FILE
git -C ~/.agents rebase --continue
~/.local/bin/code-os-skills-sync
# Or return to the exact state before the pull
git -C ~/.agents rebase --abort