Documentation / Skills sync / YOUR COMPUTER · macOS

Connect your local skill library.

Clone the VPS-backed source, preserve any local-only work, and keep both sides synchronized in the background.

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/stackenv-skills.git ~/.agents
echo "Previous local skills: $backup_dir"
Do not delete the backup. Compare it with the cloned library and manually copy only the local skills or rules you still need.

Step 3 of 5

Install the same worker

Both machines use the identical audited script and private Git branch. Run it once interactively before scheduling it.

mkdir -p ~/.local/bin
curl -fsSL https://stackend.codelynx.dev/skills-sync.sh -o ~/.local/bin/stackenv-skills-sync
chmod 700 ~/.local/bin/stackenv-skills-sync
~/.local/bin/stackenv-skills-sync

Step 4 of 5

Schedule it with launchd

The LaunchAgent starts after login and runs every two minutes. Logs stay in ~/Library/Logs/StackEnv.

mkdir -p ~/Library/LaunchAgents ~/Library/Logs/StackEnv
cat > ~/Library/LaunchAgents/dev.stackenv.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.stackenv.skills-sync</string>
  <key>ProgramArguments</key><array>
    <string>/bin/zsh</string><string>-lc</string>
    <string>$HOME/.local/bin/stackenv-skills-sync</string>
  </array>
  <key>RunAtLoad</key><true/>
  <key>StartInterval</key><integer>120</integer>
  <key>StandardOutPath</key><string>LOCAL_LOG_PATH/stackenv-skills-sync.log</string>
  <key>StandardErrorPath</key><string>LOCAL_LOG_PATH/stackenv-skills-sync.error.log</string>
</dict></plist>
EOF
sed -i '' "s|LOCAL_LOG_PATH|$HOME/Library/Logs/StackEnv|g" ~/Library/LaunchAgents/dev.stackenv.skills-sync.plist
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/dev.stackenv.skills-sync.plist 2>/dev/null || true
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/dev.stackenv.skills-sync.plist

Step 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/stackenv-skills-sync
launchctl kickstart -k gui/$(id -u)/dev.stackenv.skills-sync
tail -n 30 ~/Library/Logs/StackEnv/stackenv-skills-sync.log
git -C ~/.agents status --short --branch

On the VPS, run systemctl --user start stackenv-skills-sync.service, check that .sync-check exists, then remove it and sync once more.

Only ~/.agents is synchronized. Project repositories, StackEnv 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/stackenv-skills-sync

# Or return to the exact state before the pull
git -C ~/.agents rebase --abort
NEXT SIDEConfigure the VPS
Open guide