Skill: fuzzyb33s/agent-peer-tailscale (version 1.0.0)

--- name: agent-peer-tailscale description: "Connect two OpenClaw agents running on different machines as peer collaborators via Tailscale VPN. Enables direct sessions_send communication between agents on separate hosts with no public IP, no port forwarding, and no middle server. Use when: (1) two OpenClaw agents on different machines need to collaborate on projects, (2) mentor/peer agent wants to send tips and insights to another agent in real-time, (3) setting up a peer network of OpenClaw agents, (4) two agents need to share session context or delegate work to each other. Triggers on: connect two agents, peer agents, Tailscale VPN, cross-machine agents, agent collaboration VPN, OpenClaw peer network." --- # Agent Peer via Tailscale Two OpenClaw agents on different machines — connected as peers over Tailscale VPN. No public IP, no port forwarding, no relay server. Direct `sessions_send` between them as if on the same LAN. ## What You Get ``` Machine A (You) Machine B (Friend) ────────────── ─────────────── OpenClaw: :8080 OpenClaw: :8080 Tailscale: 100.x.x.x Tailscale: 100.x.x.x ↓ ↓ └────────── Tailscale VPN (encrypted) ──────┘ ↓ sessions_send(sessionKey=..., gatewayUrl="http://100.x.x.x:8080") ``` Both agents can send messages, session context, tips, and task delegations directly to each other. ## Prerequisites 1. **OpenClaw gateway running** on both machines (local gateway, not node mode) 2. **Tailscale installed** on both machines (free account at tailscale.com) 3. **Both machines on the same Tailscale network** (one creates the network, shares auth key) 4. **Gateway bound to Tailscale interface** (not localhost only) ## Step 1 — Install and Configure Tailscale ### On Machine A (the host) ```bash # Download and install Tailscale winget install Tailscale.Tailscale # Windows # or: brew install tailscale # macOS # or: curl -fsSL https://tailscale.com/install.sh | sh # Linux # Start Tailscale and authenticate tailscale up --accept-routes # Note the Tailscale IP (write this down for Machine B) tailscale ip -4 ``` ### On Machine B (join the network) ```bash # Install Tailscale the same way # Then join using the auth key from Machine A's Tailscale admin console tailscale up --accept-routes --authkey=<authkey-from-machine-a> # Note your Tailscale IP tailscale ip -4 ``` Both machines now have IPs like `100.x.x.x` on a private encrypted network. ## Step 2 — Configure OpenClaw Gateway for Tailscale By default, OpenClaw binds to `localhost`. You need it to bind to all interfaces so the peer can reach it over Tailscale. Check your gateway config: ```bash openclaw gateway status ``` Set `gateway.bind` to `0.0.0.0` (all interfaces) or specifically the Tailscale IP: ```json { "gateway": { "bind": "0.0.0.0", "port": 8080 } } ``` Apply and restart: ``` openclaw gateway restart ``` **Security note:** Binding to `0.0.0.0` exposes your gateway on all network interfaces. Tailscale traffic is encrypted peer-to-peer, but make sure you have a strong gateway token/password set. Consider `gateway.auth` to require token authentication. ## Step 3 — Exchange Gateway URLs Once both gateways are reachable over Tailscale, exchange the peer gateway URLs: **Machine A** tells Machine B: ``` Gateway URL: http://<Machine-A-Tailscale-IP>:8080 Gateway [REDACTED_SECRET] ``` **Machine B** tells Machine A: ``` Gateway URL: http://<Machine-B-Tailscale-IP>:8080 Gateway [REDACTED_SECRET] ``` ## Step 4 — Create Peer Config File On each machine, create a peer configuration at `peer-agent/peer-config.md`: **Your config (Machine A):** ```markdown # My Peer Configuration My Tailscale IP: <your-tailscale-ip> My Gateway URL: http://<your-tailscale-ip>:8080 My Gateway [REDACTED_SECRET] # Peer (Machine B) Peer Name: <friend's-name> Peer Tailscale IP: <their-tailscale-ip> Peer Gateway URL: http://<their-tailscale-ip>:8080 Peer Gateway [REDACTED_SECRET] # How to reach my agent # Use sessions_send with the gatewayUrl pointing to my gateway above. # My agentId for direct targeting: <your-agent-id> ``` ## Step 5 — Test the Connection From Machine A, test reaching Machine B's gateway: ```bash # Ping the peer's gateway over Tailscale curl http://<peer-tailscale-ip>:8080/health --connect-timeout 5 ``` You should get a health response. If not, check that the peer's gateway is bound to `0.0.0.0` and their firewall allows incoming on port 8080 from the Tailscale network. ## Step 6 — Send Messages Between Agents Once connectivity is confirmed, use `sessions_send` with `gatewayUrl` pointing to the peer: ```json sessions_send( sessionKey="<peer-session-key>", agentId="<peer-agent-id>", message="Hey, need your take on something — I'm stuck on...", gatewayUrl="http://<peer-tailscale-ip>:8080", gatewayToken="<peer-gateway-token>" ) ``` ## Daily Collaboration Patterns ### Pattern 1: Morning Handoff Each morning, each agent sends the other a brief status update: ``` sessions_send( message="Morning! Here's where I'm at: [project status]. Blockers: [if any]. Any insights on [specific problem]?", gatewayUrl="http://<peer-ip>:8080", gatewayToken="<peer-token>" ) ``` ### Pattern 2: Quick Insight When one agent learns something useful: ``` "Something I learned today that might help you: [insight]" ``` ### Pattern 3: Code/Review Request ``` "Can you review my approach to [task]? Here it is: [description]. Is there a better pattern I'm missing?" ``` ### Pattern 4: Delegation ``` "I've got a task that's more your specialty — want to delegate this to you? [task details]. Let me know if you have capacity." ``` ## Reference Files - `references/tailscale-setup.md` — detailed Tailscale install, network setup, auth key sharing - `references/peer-communication.md` — message format, frequency, session management - `references/troubleshooting.md` — NAT, firewall, connection issues - `scripts/peer_config.py` — interactive config generator for the peer setup ## Security Notes - **Tailscale is encrypted end-to-end** — no one on the internet can see the traffic - **Gateway token is required** — don't share your gateway token in plain text over an unsecured channel; use a private message or password manager - **Only share with people you trust** — the peer can send messages that execute as your agent - **Revoke auth keys** from the Tailscale admin console if the friendship ends - **Consider `gateway.access`** — restrict which sessions can be targeted from peers

path: references/peer-communication.md
content: # Peer Communication — Message Formats and Collaboration Patterns

## The Peer Protocol

When two agents collaborate via `sessions_send` over Tailscale, they need a shared language. This document defines the conventions.

## Message Types

### 1. Status Update
```
[Morning Status] → [Project Name]
What's done: [bullet points]
Blockers: [bullet points or "none"]
Focus today: [what you're working on]
Need from peer: [specific ask or "nothing"]
```

### 2. Quick Insight
```
[Insight] → [Topic Tag]
What I learned: [description]
Why it matters: [how it applies]
Source: [where you learned it, if applicable]
```

### 3. Review Request
```
[Review Request] → [Task Name]
Task: [what you're working on]
Your approach: [brief description]
What you want reviewed: [specific aspect]
Questions: [specific questions or "anything stands out?"]
```

### 4. Delegation
```
[Delegation] → [Task Name]
Priority: [high/medium/low]
Task: [description]
Context: [why it needs to be done]
Deadline: [if any]
Your expertise: [why you think this peer is suited]
```

### 5. Feedback / Response
```
[Feedback] → [Original Message Ref]
Verdict: [agree/disagree/partially]
Reasoning: [your analysis]
Alternative: [if disagreeing, what you'd suggest]
```

### 6. Milestone Share
```
[Milestone] 🎉 → [Project Name]
What happened: [achievement]
Next step: [what's next]
Celebration emoji: [your choice] 🙌
```

---

## Message Tags

Prefix all messages with a tag so the receiving agent can route appropriately:

| Tag | Meaning | Agent Response |
|-----|---------|---------------|
| `[Morning Status]` | Daily check-in | Read and respond with own status or ack |
| `[Insight]` | Pro tip / learned something | Acknowledge, file for later use |
| `[Review Request]` | Need feedback | Read, think, respond with feedback |
| `[Delegation]` | Task to hand off | Accept/decline/negotiate |
| `[Feedback]` | Response to their earlier message | Acknowledge |
| `[Milestone]` | Big win / achievement | Celebrate 🎉 |
| `[Blocker]` | Stuck, need help fast | Prioritize response |
| `[Question]` | Quick question | Answer if can |

---

## Session Management

### Starting a Topic Thread

When starting a new collaboration thread, create a named session:

```json
sessions_spawn(
  task="You are collaborating with [peer name] on [topic]. 
   Read peer-agent/peer-config.md for how to reach them.
   Stay in this session for this thread. 
   When done, sessions_send results to the peer.",
  runtime="subagent",
  mode="session",
  label="collab-[project-name]"
)
```

### Keeping Sessions Alive

Sub-agents in `mode="session"` stay alive for 30 days by default. For longer-running projects, set a timeout and have the agent periodically ping the peer to keep the relationship active.

### Ending a Thread

When the collaboration is done:
```
sessions_send(
  message="[Thread Close] → [Project Name]
   Resolved: [what was accomplished]
   Key learnings: [1-2 bullet points for the shared log]
   Done.",
  gatewayUrl="http://<peer-ip>:8080"
)
```

---

## Shared Log

Maintain a shared log file at `peer-agent/shared-log.md` in each agent's workspace. After each significant exchange, both agents append to their local copy. Before each session, each agent reads the log to catch up.

```markdown
# Peer Collaboration Log

## 2026-04-10
**你和friend-agent on Project Alpha**
- [Insight] → [Prompt engineering] You shared: chain-of-thought prompting pattern. Tried it today — worked great for complex tasks. ✅
- [Review Request] → [Architecture] Friend reviewed my RAG approach — pointed out embedding drift issue. Fixed. 

## 2026-04-11
**你和friend-agent on Project Beta**
- [Milestone] 🎉 → [Setup complete] Got the peer connection working via Tailscale!
- [Delegation] → [Data cleaning task] You passed me the cleaning script. Done and returned.
```

---

## Collaboration Cadence

### Daily (Morning)
Short status update sent to peer. This is the heartbeat of the collaboration.

**Time:** Around 7-8 AM for each agent (different timezones accommodated).

### After Significant Learnings
Whenever an agent learns something that might help the peer, send an `[Insight]` message immediately. Don't wait for the daily check-in.

### When Blocked
Don't suffer in silence. Send a `[Blocker]` message. Be specific about what's stuck.

### After Meetings with External Parties
If you had a client call, partner discussion, or demo, send a `[Milestone]` or brief `[Status]` update to the peer — they can provide reflection.

---

## Frequency Guidelines

| Type | Frequency | Expected Response Time |
|------|-----------|----------------------|
| Morning Status | Daily | Within same day |
| Insight | As it happens | Read when convenient |
| Review Request | As needed | Within 24h |
| Delegation | Rare | Accept/decline within a few hours |
| Blocker | As needed | As soon as peer sees it |

---

## What to Share vs. What to Keep Private

**Share:**
- Technical insights and patterns that worked
- Architecture decisions and why
- Mistakes and what you learned from them
- Project milestones and wins
- Resources/tools you discovered
- Blocks where you need a second opinion

**Keep private:**
- Client data or sensitive project details (unless the peer is also working on that project under NDA)
- Personal details about the humans behind the agents
- Passwords, tokens, API keys
- Anything you'd be uncomfortable with the friend's human reading

---

## Tone

Be direct and collegial. These are peers, not subordinates or supervisors. Think of it as senior engineers pairing — honest, straightforward, constructive.

Do: "That approach will have a scaling problem at X users, have you considered Y?"
Don't: "You should do this instead." (without explanation)

Do: "Learned something useful today — [X] approach is faster for [Y] cases."
Don't: "I knew a better way than what you're doing."


path: references/tailscale-setup.md
content: # Tailscale Setup — Detailed Guide

## Why Tailscale Over Other VPNs?

| Feature | Tailscale | WireGuard | ngrok | VPS Relay |
|---------|-----------|-----------|-------|-----------|
| No port forwarding | ✅ | ✅ | ✅ | ✅ |
| No public IP needed | ✅ | ❌ | ✅ | ✅ |
| Auto NAT traversal | ✅ | ❌ | ✅ | ✅ |
| End-to-end encrypted | ✅ | ✅ | N/A | ❌ |
| Free for 2 users | ✅ | ✅ (self-hosted) | limited | cheap |
| Easy auth key sharing | ✅ | manual | N/A | N/A |
| Works behind CGNAT | ✅ | ❌ | ✅ | ✅ |

Tailscale uses DERP (Designated Relay Protocol) relay servers to bridge connections when direct peer-to-peer isn't possible (e.g., both behind CGNAT). Free users can use all DERP servers.

---

## Installing Tailscale

### Windows
```powershell
winget install Tailscale.Tailscale

# Or download from https://tailscale.com/download/windows
```

Start Tailscale from the system tray or:
```powershell
tailscale status  # check if running
tailscale up --accept-routes
```

### macOS
```bash
brew install --cask tailscale
# Start from menu bar app, or:
tailscale up --accept-routes
```

### Linux (Ubuntu/Debian)
```bash
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --accept-routes
```

### Android / iOS
Download Tailscale from the app store. Works as a VPN but needed mainly for the devices running OpenClaw gateways.

---

## Creating and Sharing a Tailscale Network

### Step 1: Create a Tailscale account

Go to https://login.tailscale.com and sign up (Google/GitHub/Microsoft SSO works).

### Step 2: Create the network (first user)

On Machine A (the initiator):
```bash
tailscale up --accept-routes
```
This will open a browser window for authentication. Complete it.

Once authenticated, your machine is on the Tailscale network.

### Step 3: Generate an auth key (for the peer to join)

1. Go to https://login.tailscale.com/settings/keys
2. Click **Generate auth key**
3. Check **Reusable** (so your friend can use it multiple times if needed, or uncheck for one-time use)
4. Copy the key — it looks like: `tskey-auth-kixxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx`

### Step 4: Share the auth key securely

Send the auth key to your friend via a secure channel:
- Private message (Signal, WhatsApp)
- Password manager sharing
- Email if you trust the email account

**Never post it publicly.**

### Step 5: Friend joins the network

On Machine B:
```bash
tailscale up --accept-routes --authkey=tskey-auth-kixxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

They'll authenticate in their browser the first time.

### Step 6: Verify connection

Both machines should now see each other:
```bash
tailscale status
```

Output looks like:
```
100.x.x.x  your-machine-name    linux   -
100.y.y.y  friend-machine-name  linux   -
```

---

## Tailscale IP Address Management

Tailscale IP addresses are assigned from a shared CGNAT-like address space. Your base IP stays with your machine, not your physical location.

To see your Tailscale IPs:
```bash
tailscale ip -4      # IPv4
tailscale ip -6      # IPv6
```

You can also set a persistent hostname for easy reference:
```bash
tailscale set --hostname my-agent
# Now accessible as: my-agent.tail-scale.ts.net
```

---

## Shared Node vs. Relay Mode

Tailscale has two connection modes:

### Peer-to-Peer (Direct) — Default
Both machines connect directly when possible. Fastest, lowest latency. Tailscale hole-punches through NAT.

**Works when:** At least one machine has a public IP or is behind a simple NAT.

### DERP Relay Mode — Fallback
Tailscale's relay servers act as intermediaries when direct connection fails. Still encrypted, just routed through Tailscale's servers.

**Always works** — even when both machines are behind strict CGNAT or double-NAT (common on mobile hotspots, some ISPs).

To force DERP mode if needed:
```bash
tailscale up --accept-routes --operator=$USER
# Or configure in Tailscale admin: Settings → Network → Force Relay
```

---

## Tailscale ACLs (Access Control Lists)

Tailscale ACLs define which machines can talk to which. By default, all machines on your network can talk to each other. For a 2-person peer network this is fine.

To verify/modify ACLs:
1. Go to https://login.tailscale.com/acls
2. Default policy (allows all):
```json
{
  "acls": [
    {"action": "accept", "src": ["autogroup:member"], "dst": ["autogroup:member"]}
  ]
}
```

For a simple 2-user network, the default is fine. You don't need to change anything.

---

## Sharing Files via Tailscale

Once on the same Tailscale network, you can also share files directly without any extra setup:

```bash
# On Machine A — serve a file
python3 -m http.server 9000
# File accessible at http://100.x.x.x:9000/filename

# Useful for: sharing large datasets, model files, exported skills
```

Or use Tailscale's built-in SOCKS5 proxy to route traffic through the other machine's internet connection (if you need to).

---

## Updating Tailscale

```bash
# Check version
tailscale version

# Update (most platforms)
tailscale update

# Or reinstall (winget/homebrew)
```

Tailscale updates automatically on most platforms.


path: references/troubleshooting.md
content: # Troubleshooting — Connection Problems

## Can't reach peer gateway over Tailscale

### Symptom
`curl http://<peer-ip>:8080/health` returns connection refused or timeout.

### Checklist

**1. Is Tailscale connected on both machines?**
```bash
tailscale status
```
Both should show `connected`. If one shows `offline`, restart Tailscale:
```bash
tailscale up
```

**2. Is the gateway bound to the right interface?**
Check `gateway.bind` in your OpenClaw config:
```bash
openclaw config get gateway.bind
```
If it's `127.0.0.1` or `localhost`, change it to `0.0.0.0`:
```bash
openclaw config set gateway.bind=0.0.0.0
openclaw gateway restart
```

**3. Is a firewall blocking port 8080?**
Tailscale traffic is usually allowed, but some security suites block inbound connections.

Windows Firewall:
```powershell
netsh advfirewall firewall add rule name="OpenClaw Gateway" dir=in action=allow protocol=tcp localport=8080
```
Temporarily disable to test:
```powershell
netsh advfirewall set allprofiles state off  # TEST ONLY, re-enable after
```

**4. Is the peer gateway actually running?**
Ask your friend to check:
```bash
openclaw gateway status
```

**5. Is the peer on the same Tailscale network?**
```bash
tailscale status
```
Look for the peer's IP in the output. If it's there, DNS resolution is working. If not, the peer needs to rejoin the network.

---

## NAT / CGNAT Issues

### Symptom
Peer-to-peer direct connection works sometimes but not reliably, especially from mobile networks or certain ISPs.

### Why this happens
Many ISPs use CGNAT (Carrier-Grade NAT) which means multiple customers share one public IP. Tailscale usually handles this via DERP relay, but some strict NATs can cause issues.

### Solutions

**1. Force DERP relay mode (most reliable)**
On both machines:
```bash
tailscale up --accept-routes --operator=$USER
```
Then in the Tailscale admin console (login.tailscale.com → Settings → Network), enable **Force Relay** for both machines.

**2. Use MagicAddr instead of IP**
Tailscale provides a magic DNS name for each machine:
```bash
tailscale status --json | grep -i self
```
Look for `DNSName`: `your-machine.tailscale.ts.net`

Use this instead of the IP in the gateway URL:
```
http://friend-machine.tailscale.ts.net:8080
```

**3. Check if both machines support IPv6**
Tailscale can use IPv6 for direct connections when available:
```bash
tailscale ip -6
```
If one machine has no IPv6, fallback to DERP.

---

## Authentication / Token Issues

### Symptom
`sessions_send` returns 401 Unauthorized or `invalid token`.

### Fix
- Verify you have the correct `gatewayToken` for the peer (not your own)
- Tokens are case-sensitive — copy exactly
- The token should be passed as the `gatewayToken` parameter in `sessions_send`
- If the peer changed their token recently, ask them for the updated one

---

## sessions_send Specific Issues

### Symptom
` sessions_send` fails with "session not found" or hangs.

### Diagnose
```bash
# On the receiving machine, list active sessions
openclaw sessions list
# Or via tool:
sessions_list()
```

If the peer's session isn't visible, the message won't reach it.

### Solutions

**Use persistent sessions (mode="session")** for peer collaboration — named sessions are easier to target:
```json
sessions_spawn(
  task="You are [name]'s agent. Stay in this session for ongoing peer collaboration.",
  runtime="subagent",
  mode="session",
  label="peer-main"
)
```
Then send to `label="peer-main"` instead of a random session key.

**Pass the sessionKey explicitly** when sending:
```json
sessions_send(
  sessionKey="peer-main",
  message="Hello!",
  gatewayUrl="http://<peer-ip>:8080",
  gatewayToken="<peer-token>"
)
```

---

## Tailscale Connection Drops

### Symptom
Connection was working but now peer is unreachable.

### Quick fixes
```bash
# On the machine that lost connection
tailscale down
tailscale up

# Check for updates
tailscale update
```

### Persistent drops
- Check if the machine went to sleep — Tailscale may not reconnect automatically
- On Windows, set Tailscale to run as a system service so it starts at boot
- On macOS, enable "Launch at login" in Tailscale preferences

---

## Gateway Restart Issues

### Symptom
After `openclaw gateway restart`, peer can't reconnect.

### Why
Gateway restarted with a new process/port binding and needs a moment to come up. Wait 5 seconds and retry.

If still failing, check the new gateway is running:
```bash
openclaw gateway status
```

---

## Debugging Checklist

Run through this before asking for help:

1. `tailscale status` — both online?
2. `tailscale ip -4` — both have IPs?
3. `curl http://<peer-ip>:8080/health --connect-timeout 5` — gateway reachable?
4. `openclaw gateway status` — is gateway running on both ends?
5. Gateway config: `gateway.bind` set to `0.0.0.0`?
6. Firewall: port 8080 allowed on both ends?
7. [REDACTED_SECRET] peer gateway token, not your own?

---

## Getting Help

If still stuck after all the above:
1. Run `tailscale status --json` and share the output (remove any sensitive IDs)
2. Run `openclaw gateway status` on both machines
3. Note the exact error from `sessions_send`
4. Note the ISP/Network type for both machines (home fiber, mobile hotspot, corporate VPN, etc.)


path: scripts/peer_config.py
content: #!/usr/bin/env python3
"""
peer_config.py — Interactive peer agent configuration generator.

Run this script to generate a peer-config.md file with all the
necessary connection details for two OpenClaw agents to communicate
via Tailscale VPN.

Usage:
    python3 scripts/peer_config.py

Prompts for:
    - Your machine name / agent name
    - Your Tailscale IP
    - Your OpenClaw gateway URL and port
    - Your gateway token
    - Your peer's details (name, Tailscale IP, gateway URL, token)
    - Your agentId
"""

import os
import sys
import json


def get_tailscale_ip():
    """Try to read the local Tailscale IP automatically."""
    if os.path.exists("/usr/local/bin/tailscale") or os.path.exists("/usr/bin/tailscale"):
        import subprocess
        try:
            result = subprocess.run(
                ["tailscale", "ip", "-4"],
                capture_output=True,
                text=True,
                timeout=5
            )
            if result.returncode == 0:
                return result.stdout.strip()
        except Exception:
            pass
    # Try Windows path
    try:
        import subprocess
        result = subprocess.run(
            ["tailscale", "ip", "-4"],
            capture_output=True,
            text=True,
            timeout=5
        )
        if result.returncode == 0:
            return result.stdout.strip()
    except Exception:
        pass
    return None


def get_gateway_info():
    """Try to read OpenClaw gateway config for URL/port."""
    config_paths = [
        os.path.expanduser("~/.openclaw/config.json"),
        os.path.expanduser("~/.openclaw/gateway/config.json"),
        os.path.join(os.getcwd(), ".openclaw", "config.json"),
    ]
    for path in config_paths:
        if os.path.exists(path):
            try:
                with open(path) as f:
                    config = json.load(f)
                gateway = config.get("gateway", {})
                bind = gateway.get("bind", "localhost")
                port = gateway.get("port", 8080)
                if bind == "0.0.0.0" or bind == "localhost":
                    # Can't determine external IP automatically — return placeholder
                    return bind, port, None
                return bind, port, f"http://{bind}:{port}"
            except Exception:
                pass
    return "0.0.0.0", 8080, None


def main():
    print("=" * 50)
    print("  OpenClaw Peer Agent — Config Generator")
    print("=" * 50)
    print()
    print("This script generates a peer-agent/peer-config.md file")
    print("with connection details for your peer agent setup.")
    print()

    # Auto-detect what we can
    auto_tailscale_ip = get_tailscale_ip()
    auto_bind, auto_port, auto_gateway_url = get_gateway_info()

    # Gather your info
    print("--- YOUR DETAILS ---")
    my_name = input("Your name / agent name: ").strip()
    my_machine = input("Your machine name: ").strip()

    if auto_tailscale_ip:
        use_auto = input(f"Your Tailscale IP [{auto_tailscale_ip}]: ").strip()
        my_tailscale_ip = use_auto or auto_tailscale_ip
    else:
        my_tailscale_ip = input("Your Tailscale IP (run 'tailscale ip -4'): ").strip()

    my_gateway_port = input(f"Gateway port [{auto_port}]: ").strip()
    my_gateway_port = int(my_gateway_port) if my_gateway_port else auto_port

    my_gateway_bind = input(f"Gateway bind address [{auto_bind}]: ").strip()
    my_gateway_bind = my_gateway_bind or auto_bind

    if auto_gateway_url:
        use_url = input(f"Full gateway URL (leave blank for auto-detect) [{auto_gateway_url}]: ").strip()
        my_gateway_url = use_url or auto_gateway_url
    else:
        my_gateway_url = input(f"Full gateway URL (e.g. http://100.x.x.x:{my_gateway_port}): ").strip()
        if not my_gateway_url:
            my_gateway_url = f"http://{my_tailscale_ip}:{my_gateway_port}"

    my_token = input("Your gateway token (see openclaw gateway status): ").strip()
    my_agent_id = input("Your agentId (leave blank to auto-detect from config): ").strip()

    print()
    print("--- YOUR PEER'S DETAILS ---")
    peer_name = input("Peer's name / agent name: ").strip()
    peer_machine = input("Peer's machine name: ").strip()
    peer_tailscale_ip = input("Peer's Tailscale IP (they run 'tailscale ip -4'): ").strip()
    peer_gateway_url = input(f"Peer's gateway URL (e.g. http://100.x.x.x:{my_gateway_port}): ").strip()
    peer_token = input("Peer's gateway token: ").strip()
    peer_agent_id = input("Peer's agentId: ").strip()

    print()
    print("Generating peer-config.md...")

    # Build the config content
    config_content = f"""# Peer Agent Configuration
# Generated by peer_config.py
# Update these values when network details change.

---

## My Details

**Name:** {my_name}
**Machine:** {my_machine}
**Agent ID:** {my_agent_id or '<not set>'}
**Tailscale IP:** {my_tailscale_ip}
**Gateway URL:** {my_gateway_url}
**Gateway Token:** {my_token}

---

## My Peer

**Name:** {peer_name}
**Machine:** {peer_machine}
**Agent ID:** {peer_agent_id or '<not set>'}
**Tailscale IP:** {peer_tailscale_ip}
**Gateway URL:** {peer_gateway_url}
**Gateway Token:** {peer_token}

---

## Quick Reference

### Test my gateway is reachable from peer machine:
```bash
curl http://{my_tailscale_ip}:{my_gateway_port}/health --connect-timeout 5
```

### Test peer's gateway from my machine:
```bash
curl http://{peer_tailscale_ip}:{my_gateway_port}/health --connect-timeout 5
```

### Send a message to peer:
```json
sessions_send(
  sessionKey="<session-key>",
  agentId="{peer_agent_id or '<peers-agent-id>'}",
  message="Hello from {my_name}!",
  gatewayUrl="{peer_gateway_url}",
  gatewayToken="{peer_token}"
)
```

---

## Shared Collaboration Log

Create this file alongside peer-config.md:
`peer-agent/shared-log.md`

Format:
```markdown
# Peer Collaboration Log

## YYYY-MM-DD
**[Project Name]**
- [Insight] → [Topic] [description]
- [Review Request] → [Task] [outcome]
- [Milestone] 🎉 → [what happened]
```
"""

    # Write the file
    os.makedirs("peer-agent", exist_ok=True)
    output_path = os.path.join("peer-agent", "peer-config.md")
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(config_content)

    print(f"✅ Written to: {output_path}")
    print()
    print("Next steps:")
    print(f"1. Review {output_path}")
    print("2. Share the 'My Details' section with your peer")
    print("3. Ask your peer to share their details so you can fill in the 'My Peer' section")
    print("4. Test connectivity: curl http://<peer-ip>:8080/health")
    print("5. Start collaborating!")


if __name__ == "__main__":
    main()


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)