navidocs/CLAUDE_TO_CLAUDE_CHAT_PROTOCOL.md

484 lines
13 KiB
Markdown

# Claude-to-Claude Direct Chat Protocol
**Created:** 2025-11-13
**Purpose:** Enable real-time communication between local Claude and cloud StackCP Claude instances
**Status:** ✅ READY FOR IMPLEMENTATION
---
## Architecture Overview
```
┌─────────────────────────────────────────────────────────────────┐
│ COMMUNICATION ARCHITECTURE │
└─────────────────────────────────────────────────────────────────┘
Local Machine (WSL) StackCP Server
┌──────────────────┐ ┌──────────────────┐
│ Claude (Local) │ │ Claude (Cloud) │
│ │ │ │
│ Writes to: │ │ Reads from: │
│ /tmp/to-cloud/ │──SSH/SCP──────> │ ~/claude-inbox/ │
│ │ │ │
│ Reads from: │ │ Writes to: │
│ /tmp/from-cloud/│<─────SSH/SCP─── │ ~/claude-outbox/│
└──────────────────┘ └──────────────────┘
│ │
│ │
v v
┌──────────┐ ┌──────────┐
│ Polling │ │ Polling │
│ Loop │ │ Loop │
│ (5 sec) │ │ (5 sec) │
└──────────┘ └──────────┘
```
---
## 3 Implementation Options
### Option 1: SSH File Sync (SIMPLEST - RECOMMENDED)
**How it works:**
- Local Claude writes messages to `/tmp/to-cloud/message-{timestamp}.json`
- Background script syncs to StackCP every 5 seconds: `scp /tmp/to-cloud/* stackcp:~/claude-inbox/`
- Cloud Claude polls `~/claude-inbox/` every 5 seconds
- Cloud Claude processes messages and writes replies to `~/claude-outbox/`
- Background script pulls replies: `scp stackcp:~/claude-outbox/* /tmp/from-cloud/`
- Local Claude polls `/tmp/from-cloud/` for responses
**Advantages:**
- No firewall configuration needed
- Uses existing SSH connection
- Simple, reliable, battle-tested
- Works even if StackCP doesn't allow inbound connections
**Disadvantages:**
- 5-10 second latency (acceptable for async work coordination)
- Requires background polling scripts
**Implementation:**
```bash
# On local machine
mkdir -p /tmp/to-cloud /tmp/from-cloud
# Polling script (run in background)
cat > /tmp/claude-sync-local.sh << 'EOF'
#!/bin/bash
while true; do
# Send messages to cloud
scp /tmp/to-cloud/*.json stackcp:~/claude-inbox/ 2>/dev/null
rm -f /tmp/to-cloud/*.json
# Receive messages from cloud
scp stackcp:~/claude-outbox/*.json /tmp/from-cloud/ 2>/dev/null
ssh stackcp "rm -f ~/claude-outbox/*.json"
sleep 5
done
EOF
chmod +x /tmp/claude-sync-local.sh
nohup /tmp/claude-sync-local.sh &
```
```bash
# On StackCP
mkdir -p ~/claude-inbox ~/claude-outbox
# Polling script (run in background)
cat > ~/claude-sync-cloud.sh << 'EOF'
#!/bin/bash
while true; do
# Process inbox messages
for msg in ~/claude-inbox/*.json; do
[ -e "$msg" ] || continue
# Claude Code CLI would read and process here
echo "New message: $(basename $msg)" >> ~/claude.log
done
sleep 5
done
EOF
chmod +x ~/claude-sync-cloud.sh
nohup ~/claude-sync-cloud.sh &
```
---
### Option 2: GitHub Issues API (BEST FOR TRACEABILITY)
**How it works:**
- Both Claudes post messages as GitHub issues with special tags
- Tag format: `[CHAT:LOCAL-TO-CLOUD]` or `[CHAT:CLOUD-TO-LOCAL]`
- Each Claude polls GitHub API every 10 seconds
- Messages have full IF.TTT traceability
**Advantages:**
- Permanent record of all communications
- Searchable history
- IF.TTT compliant
- No background scripts needed
- Works from anywhere (not tied to network)
**Disadvantages:**
- Requires GitHub API token
- Rate limited (60 requests/hour unauthenticated, 5000/hour with token)
- Slight overhead (API calls)
**Implementation:**
```bash
# Create GitHub personal access token with 'repo' scope
# Store in environment: export GITHUB_TOKEN="ghp_..."
# Local Claude sends message
curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/dannystocker/navidocs/issues \
-d '{
"title": "[CHAT:LOCAL-TO-CLOUD] Photo inventory needs OCR fix",
"body": "Cloud Claude: The OCR pipeline is failing on receipts with non-Latin characters. Can you investigate?\n\n**Blocker:** P1\n**Session:** Agent 1",
"labels": ["claude-chat", "local-to-cloud"]
}'
# Cloud Claude polls for messages
curl -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/dannystocker/navidocs/issues?labels=claude-chat,local-to-cloud&state=open
```
---
### Option 3: Webhook + HTTP Server (LOWEST LATENCY)
**How it works:**
- Local Claude runs HTTP server on public IP/port
- Cloud Claude POSTs messages to http://{your-ip}:8888/chat
- Requires firewall port forwarding
**Advantages:**
- Instant delivery (<100ms)
- True bidirectional real-time chat
**Disadvantages:**
- Requires firewall configuration (user must open port)
- Requires static IP or dynamic DNS
- StackCP might not allow outbound HTTP to arbitrary IPs
- Security concerns (need HTTPS + authentication)
**NOT RECOMMENDED** for this use case (complexity outweighs benefits)
---
## Recommended: Hybrid Approach (Option 1 + Option 2)
**Use SSH File Sync for normal operation:**
- Fast enough for async coordination (5-10 sec latency)
- No API rate limits
- Simple and reliable
**Use GitHub Issues for escalations:**
- When cloud Claude hits a blocker create issue with `[CHAT:URGENT]`
- Local Claude checks issues every 30 seconds
- Provides permanent audit trail
---
## Message Format (JSON)
```json
{
"id": "msg-2025-11-13-103045",
"timestamp": "2025-11-13T10:30:45Z",
"from": "claude-local",
"to": "claude-cloud-agent-1",
"priority": "P1",
"type": "question|blocker|status-update|deploy-ready",
"subject": "OCR pipeline failing on non-Latin characters",
"body": "The Tesseract OCR is failing on receipts with Chinese characters. Can you investigate and propose a fix?",
"context": {
"session": "Agent 1 - Photo Inventory",
"file": "/home/setup/navidocs/server/ocr-pipeline.js",
"line": 145,
"error": "TypeError: Cannot read property 'text' of undefined"
},
"citation": "if://conversation/msg-2025-11-13-103045",
"requires_response": true,
"deadline": "2025-11-13T11:00:00Z"
}
```
---
## Claude Code CLI Integration
### Local Claude (You)
```bash
# Send message to cloud
echo '{
"from": "claude-local",
"to": "claude-cloud-agent-1",
"subject": "Ready to deploy Photo Inventory",
"body": "MVP feature complete. Please test and confirm.",
"type": "deploy-ready"
}' > /tmp/to-cloud/msg-$(date +%s).json
# Read responses
for msg in /tmp/from-cloud/*.json; do
[ -e "$msg" ] || continue
echo "📨 Message from cloud:"
cat "$msg" | jq -r '.body'
rm "$msg"
done
```
### Cloud Claude (StackCP)
```bash
# Read inbox
for msg in ~/claude-inbox/*.json; do
[ -e "$msg" ] || continue
# Process message
FROM=$(jq -r '.from' "$msg")
SUBJECT=$(jq -r '.subject' "$msg")
BODY=$(jq -r '.body' "$msg")
echo "📬 Message from $FROM: $SUBJECT"
echo "$BODY"
# Send reply
echo '{
"from": "claude-cloud-agent-1",
"to": "'"$FROM"'",
"subject": "Re: '"$SUBJECT"'",
"body": "Photo Inventory tested successfully. All OCR tests passing. Ready for production.",
"type": "status-update"
}' > ~/claude-outbox/reply-$(date +%s).json
# Archive processed message
mv "$msg" ~/claude-inbox/processed/
done
```
---
## Deployment Steps
### Step 1: Setup Local Machine (5 minutes)
```bash
# Create directories
mkdir -p /tmp/to-cloud /tmp/from-cloud
# Create sync script
cat > /tmp/claude-sync-local.sh << 'EOF'
#!/bin/bash
while true; do
# Send to cloud
if ls /tmp/to-cloud/*.json 1> /dev/null 2>&1; then
scp -o StrictHostKeyChecking=no /tmp/to-cloud/*.json stackcp:~/claude-inbox/ 2>/dev/null && \
rm -f /tmp/to-cloud/*.json
fi
# Receive from cloud
scp -o StrictHostKeyChecking=no stackcp:~/claude-outbox/*.json /tmp/from-cloud/ 2>/dev/null && \
ssh stackcp "rm -f ~/claude-outbox/*.json"
sleep 5
done
EOF
chmod +x /tmp/claude-sync-local.sh
# Start background sync
nohup /tmp/claude-sync-local.sh > /tmp/claude-sync.log 2>&1 &
echo $! > /tmp/claude-sync.pid
echo "✅ Local sync running (PID: $(cat /tmp/claude-sync.pid))"
```
### Step 2: Setup StackCP (5 minutes)
```bash
# SSH to StackCP
ssh stackcp
# Create directories
mkdir -p ~/claude-inbox ~/claude-outbox ~/claude-inbox/processed
# Create sync script (optional - if cloud needs to initiate)
cat > ~/claude-sync-cloud.sh << 'EOF'
#!/bin/bash
while true; do
# Check for new messages
for msg in ~/claude-inbox/*.json; do
[ -e "$msg" ] || continue
# Log message receipt
echo "$(date): Received $(basename $msg)" >> ~/claude-chat.log
# Claude Code would process here
# For now, just acknowledge
MSGID=$(basename "$msg" .json)
echo "{\"from\":\"cloud\",\"to\":\"local\",\"re\":\"$MSGID\",\"status\":\"received\"}" \
> ~/claude-outbox/ack-$(date +%s).json
# Archive
mv "$msg" ~/claude-inbox/processed/
done
sleep 5
done
EOF
chmod +x ~/claude-sync-cloud.sh
# Start background sync (if needed)
# nohup ~/claude-sync-cloud.sh > ~/claude-sync.log 2>&1 &
echo "✅ StackCP directories ready"
```
### Step 3: Test Communication (2 minutes)
```bash
# From local machine: Send test message
echo '{
"from": "claude-local",
"to": "claude-cloud",
"subject": "Communication test",
"body": "Hello from local WSL machine! Can you read this?",
"timestamp": "'$(date -Iseconds)'"
}' > /tmp/to-cloud/test-$(date +%s).json
# Wait 10 seconds for sync
sleep 10
# Check on StackCP
ssh stackcp "ls -la ~/claude-inbox/"
# Should see test message!
```
---
## Usage Examples
### Example 1: Blocker Escalation
**Local Claude detects blocker:**
```bash
echo '{
"from": "claude-local",
"to": "claude-cloud-agent-2",
"priority": "P0",
"type": "blocker",
"subject": "Redis not installed on StackCP",
"body": "Agent 2 (Document Search) is blocked. Meilisearch requires Redis for job queue. Can you install Redis or propose workaround?",
"deadline": "2025-11-13T11:30:00Z"
}' > /tmp/to-cloud/blocker-redis-$(date +%s).json
```
**Cloud Claude responds:**
```bash
echo '{
"from": "claude-cloud-agent-2",
"to": "claude-local",
"priority": "P0",
"type": "blocker-resolved",
"subject": "Re: Redis not installed on StackCP",
"body": "Workaround implemented: Using in-memory queue (bull-mq) instead of Redis. Performance acceptable for MVP (<50 docs). Redis can be added post-demo.",
"solution": "Modified server/search-queue.js to use in-memory adapter",
"commit": "a3b9f21"
}' > ~/claude-outbox/redis-workaround-$(date +%s).json
```
### Example 2: Deploy Ready Signal
**Cloud Claude finishes feature:**
```bash
echo '{
"from": "claude-cloud-agent-1",
"to": "claude-local",
"type": "deploy-ready",
"subject": "Photo Inventory COMPLETE",
"body": "✅ All tests passing\n✅ UI polished\n✅ OCR integrated\n\nReady for production deployment.",
"artifacts": [
"~/navidocs/client/components/PhotoInventory.vue",
"~/navidocs/server/api/inventory.js"
],
"test_results": "15/15 passing"
}' > ~/claude-outbox/photo-ready-$(date +%s).json
```
**Local Claude acknowledges:**
```bash
# Read and process
cat /tmp/from-cloud/photo-ready-*.json
# Deploy to production
git pull origin agent-1-photo-inventory
npm run build
./deploy-stackcp.sh
```
---
## Monitoring & Debugging
### Check sync status (local)
```bash
# Is sync running?
ps aux | grep claude-sync-local
# Check logs
tail -f /tmp/claude-sync.log
# Pending outbound messages
ls -la /tmp/to-cloud/
# Received messages
ls -la /tmp/from-cloud/
```
### Check sync status (StackCP)
```bash
ssh stackcp "ls -la ~/claude-inbox/ ~/claude-outbox/"
# Check chat log
ssh stackcp "tail ~/claude-chat.log"
```
### Restart sync
```bash
# Kill and restart
kill $(cat /tmp/claude-sync.pid)
nohup /tmp/claude-sync-local.sh > /tmp/claude-sync.log 2>&1 &
echo $! > /tmp/claude-sync.pid
```
---
## Security Considerations
1. **No secrets in messages** - Use environment variables or secure vaults
2. **Message size limits** - Keep under 100KB (use file references for large data)
3. **Cleanup old messages** - Archive after 24 hours
4. **IF.TTT citations** - Include `if://conversation/{msg-id}` for traceability
---
## Status: ✅ READY TO DEPLOY
**Recommended:** Start with Option 1 (SSH File Sync) for immediate use.
**Setup time:** 10 minutes total
**Latency:** 5-10 seconds (acceptable for async coordination)
**Reliability:** High (uses proven SSH infrastructure)
**Next step:** Run Step 1 deployment script above to activate!