$npx -y skills add toroleapinc/claude-brain --skill brain-joinJoin an existing brain sync network from another machine. Pulls the consolidated brain and merges with any local state.
| 1 | The user wants to join an existing brain network from this machine. |
| 2 | |
| 3 | The Git remote URL is provided as: $ARGUMENTS |
| 4 | |
| 5 | ## Steps |
| 6 | |
| 7 | 1. Check dependencies (git, jq or python3). |
| 8 | |
| 9 | 2. Validate the remote URL for security: |
| 10 | ```bash |
| 11 | source "${CLAUDE_PLUGIN_ROOT}/scripts/common.sh" |
| 12 | validate_remote_url "$ARGUMENTS" |
| 13 | ``` |
| 14 | If the URL appears to point to a PUBLIC repo, warn the user and ask for confirmation. |
| 15 | |
| 16 | 3. Show current local brain inventory: |
| 17 | ``` |
| 18 | bash "${CLAUDE_PLUGIN_ROOT}/scripts/status.sh" |
| 19 | ``` |
| 20 | |
| 21 | 4. **Show security notice:** |
| 22 | - "Joining a brain network means:" |
| 23 | - " - Your local brain data will be PUSHED to the remote repository" |
| 24 | - " - Remote brain data (skills, agents, rules) will be IMPORTED to your machine" |
| 25 | - " - Auto-sync will run on every Claude Code session start/end" |
| 26 | - "" |
| 27 | - "Only join brain networks you trust — imported skills and agents execute with Claude's permissions." |
| 28 | |
| 29 | 5. Clone the brain repo: |
| 30 | ```bash |
| 31 | git clone "$ARGUMENTS" ~/.claude/brain-repo |
| 32 | ``` |
| 33 | If the directory exists, do `git -C ~/.claude/brain-repo pull origin main` instead. |
| 34 | |
| 35 | 6. Check if the network uses encryption: |
| 36 | ```bash |
| 37 | # Check for recipients file indicating encryption |
| 38 | if [ -f ~/.claude/brain-repo/meta/recipients.txt ]; then |
| 39 | echo "This brain network uses age encryption." |
| 40 | |
| 41 | if ! command -v age-keygen &>/dev/null; then |
| 42 | echo "ERROR: age not found. Install it from https://github.com/FiloSottile/age" |
| 43 | echo "On macOS: brew install age" |
| 44 | echo "On Ubuntu/Debian: apt install age" |
| 45 | exit 1 |
| 46 | fi |
| 47 | |
| 48 | echo "" |
| 49 | echo "You need to set up age encryption to join this network." |
| 50 | echo "Options:" |
| 51 | echo " 1. Generate a new age keypair for this machine" |
| 52 | echo " 2. Use an existing age private key" |
| 53 | echo "" |
| 54 | read -p "Generate new keypair? (y/n): " -r generate_key |
| 55 | |
| 56 | if [ "$generate_key" = "y" ] || [ "$generate_key" = "Y" ]; then |
| 57 | # Generate new keypair |
| 58 | source "${CLAUDE_PLUGIN_ROOT}/scripts/common.sh" |
| 59 | IDENTITY_FILE="${HOME}/.claude/brain-age-key.txt" |
| 60 | age-keygen -o "$IDENTITY_FILE" |
| 61 | chmod 600 "$IDENTITY_FILE" |
| 62 | |
| 63 | # Extract public key |
| 64 | PUBLIC_KEY=$(grep "# public key:" "$IDENTITY_FILE" | cut -d' ' -f4) |
| 65 | echo "" |
| 66 | echo "Generated age keypair. Your public key is:" |
| 67 | echo "$PUBLIC_KEY" |
| 68 | echo "" |
| 69 | echo "IMPORTANT: Share this public key with the brain network owner" |
| 70 | echo "so they can add it to the recipients file." |
| 71 | echo "" |
| 72 | echo "The network owner should run:" |
| 73 | echo " echo '$PUBLIC_KEY' >> ~/.claude/brain-repo/meta/recipients.txt" |
| 74 | echo " git add meta/recipients.txt && git commit -m 'Add machine: $(hostname)' && git push" |
| 75 | echo "" |
| 76 | read -p "Press Enter when the network owner has added your public key..." |
| 77 | |
| 78 | # Pull to get updated recipients |
| 79 | git -C ~/.claude/brain-repo pull origin main |
| 80 | |
| 81 | REGISTER_FLAGS="--encrypt" |
| 82 | else |
| 83 | echo "Please place your existing age private key at: ~/.claude/brain-age-key.txt" |
| 84 | echo "Make sure it's readable only by you: chmod 600 ~/.claude/brain-age-key.txt" |
| 85 | read -p "Press Enter when ready..." |
| 86 | |
| 87 | if [ ! -f ~/.claude/brain-age-key.txt ]; then |
| 88 | echo "ERROR: Age private key not found at ~/.claude/brain-age-key.txt" |
| 89 | exit 1 |
| 90 | fi |
| 91 | |
| 92 | REGISTER_FLAGS="--encrypt" |
| 93 | fi |
| 94 | else |
| 95 | echo "This brain network does not use encryption." |
| 96 | REGISTER_FLAGS="" |
| 97 | fi |
| 98 | ``` |
| 99 | |
| 100 | 7. Register this machine: |
| 101 | ```bash |
| 102 | if [ -n "$REGISTER_FLAGS" ]; then |
| 103 | bash "${CLAUDE_PLUGIN_ROOT}/scripts/register-machine.sh" "$ARGUMENTS" $REGISTER_FLAGS |
| 104 | else |
| 105 | bash "${CLAUDE_PLUGIN_ROOT}/scripts/register-machine.sh" "$ARGUMENTS" |
| 106 | fi |
| 107 | ``` |
| 108 | |
| 109 | 8. Show what's in the consolidated brain vs what's local. Run export first: |
| 110 | ```bash |
| 111 | MACHINE_ID=$(cat ~/.claude/brain-config.json | jq -r '.machine_id') |
| 112 | mkdir -p ~/.claude/brain-repo/machines/${MACHINE_ID} |
| 113 | bash "${CLAUDE_PLUGIN_ROOT}/scripts/export.sh" --output ~/.claude/brain-repo/machines/${MACHINE_ID}/brain-snapshot.json |
| 114 | ``` |
| 115 | |
| 116 | 9. Ask the user how to handle existing local data: |
| 117 | - **Merge** (recommended): Merge local brain into consolidated |
| 118 | - **Overwrite**: Replace local with consolidated brain |
| 119 | - **Keep local**: Keep local as-is, only add new items from consolidated |
| 120 | |
| 121 | 10. Based on choice: |
| 122 | - **Merge**: Run merge-structured.sh then merge-semantic.sh between local snapshot and consolidated |
| 123 | - **Overwrite**: Run import.sh directly with consolidated brain |
| 124 | - **Keep local**: Run import.sh but skip files that already exist locally |
| 125 | |
| 126 | 11. Push the updated state: |
| 127 | ```bash |
| 128 | cd ~/.claude/brain-repo |
| 129 | git add machines/ consolidated/ meta/ |
| 130 | git commit -m "Join: $(hostname) joined brain network" |
| 131 | g |