Skip to content

feat: PM Daemon Tailscale Integration#36

Open
ebowwa wants to merge 9 commits intodevfrom
feat/pm-daemon-tailscale-integration
Open

feat: PM Daemon Tailscale Integration#36
ebowwa wants to merge 9 commits intodevfrom
feat/pm-daemon-tailscale-integration

Conversation

@ebowwa
Copy link
Owner

@ebowwa ebowwa commented Jan 31, 2026

Summary

  • Add TailscaleService for monitoring Tailscale mesh network
  • Add new HTTP API endpoints for Tailscale status, IPs, and peers
  • Add ConnectionInfo types for internet connectivity monitoring
  • Minor enhancements to pm-commands, pm-monitor, and telegram services

API Endpoints Added

  • GET /api/tailscale/status - Tailscale connection status
  • GET /api/tailscale/ips - All Tailscale IPs
  • GET /api/tailscale/peers - All mesh peers
  • GET /api/tailscale/peers/online - Online peers only

Changes

  • 8 files changed, 485 insertions(+), 174 deletions(-)
  • Removes old ralph-iterative session state file

🤖 Generated with Claude Code

ebowwa and others added 9 commits January 28, 2026 21:53
Implements the PM Daemon design from docs/internal/docs/PM-DAEMON-DESIGN.md.

The PM Daemon is an LLM-powered AI agent that runs as a persistent loop on
each seed node, providing a 24/7 project manager interface via Telegram.

**New Services:**
- services/telegram.ts - Telegram Bot API client (long-polling, exponential backoff)
- services/node-registry.ts - Multi-node registry with health checks
- services/pm-commands.ts - Slash command router (/status, /loops, /start, /stop, etc.)
- services/pm-monitor.ts - Monitor loop (detects completions, errors, stalls)
- services/pm-brain.ts - Claude Code session manager via doppler subprocess

**Configuration:**
- src/config/nodes.yaml - Node registry template
- .env.example - Added PM_DAEMON_ENABLED, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID
- CLAUDE.md - PM daemon persona/system prompt

**Changes:**
- src/types/index.ts - Added PM daemon types (Telegram, NodeRegistry, MonitorEvent, etc.)
- src/index.ts - Conditional PM daemon startup when PM_DAEMON_ENABLED=true

**Doppler Secrets (seed/prd):**
- TELEGRAM_BOT_TOKEN - Bot token for @SimulationapiBot
- TELEGRAM_CHAT_ID - Allowed chat ID for operator
- PM_DAEMON_ENABLED - Enables PM daemon on all nodes

Co-Authored-By: Claude <noreply@anthropic.com>
Previously spawned a new Claude Code session per message (stateless).
Now maintains a persistent virtual session with conversation history.

Changes:
- pmBrain.start() called on PM daemon startup
- pmBrain.stop() called on shutdown
- Each message includes last 20 messages for context
- Max 100 messages stored (with system prompt preserved)
- Processing lock prevents concurrent messages

This gives the PM "memory" - it remembers previous context and can
reference earlier parts of the conversation.

Co-Authored-By: Claude <noreply@anthropic.com>
Two types of Claude sessions:
1. Persistent session (main brain)
   - One long-running doppler run -- claude process
   - Communicates via stdin/stdout pipes
   - Maintains conversation memory
   - Auto-restarts on crash

2. Spawned workers (for isolated tasks)
   - Fresh claude -p instances for one-off tasks
   - Don't affect persistent session memory
   - Can run multiple in parallel

Changes:
- Added PersistentClaudeSession class with stdin/stdout handling
- pmBrain.processMessage() uses persistent session
- pmBrain.spawnWorker() spawns fresh instances
- pmBrain.spawnWorkers() for parallel execution

Co-Authored-By: Claude <noreply@anthropic.com>
Removed all the manual conversation tracking that I overengineered.
Claude Code already has built-in memory and context management.

What it does now:
- Spawn ONE persistent doppler run -- claude process
- Pipe stdin/stdout for communication
- Claude handles all memory (no manual tracking needed)
- Monitor loop injects context as messages
- Spawned workers available for parallel tasks

600+ lines → 410 lines

Co-Authored-By: Claude <noreply@anthropic.com>
PM daemon services now live in src/services/daemon/:
- telegram.ts
- pm-brain.ts
- pm-commands.ts
pm-monitor.ts
- node-registry.ts

Core services remain in src/services/:
- git.ts
-ralph.ts
-setup.ts

Co-Authored-By: Claude <noreply@anthropic.com>
- Add real-time bidirectional WebSocket for peeking into running Claude sessions
- Store process handles (stdin/stdout) for active Ralph loops
- Add WS endpoint: /api/ralph-loops/:id/ws
- Stream Claude stdout → WebSocket for visibility
- Relay WebSocket messages → Claude stdin for oversight
- Remove node-registry (deferred to multi-node architecture)
- Update PM daemon to single-node mode
- Add NODE-REGISTRY-DESIGN.md for future multi-node reference

Co-Authored-By: Claude <noreply@anthropic.com>
- Rename pm-brain.ts → daemon-layer-agent.ts
- Update class name: PmBrainService → DaemonLayerAgentService
- Update imports and references in index.ts

Co-Authored-By: Claude <noreply@anthropic.com>
- Install @ebowwa/lane from npm using bun install
- Symlink ~/.lane-install/node_modules/.bin/lane to ~/.local/bin/lane
- Avoids broken bun -g and unnecessary git clone
- Update tests for npm-based installation

Co-Authored-By: Claude <noreply@anthropic.com>
- Add TailscaleService for status, IPs, peers
- Add /api/tailscale/* endpoints to node-agent HTTP API
- Add ConnectionInfo types for connectivity monitoring
- Update pm-commands, pm-monitor, telegram with minor enhancements
- Remove old ralph-iterative session state

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant