Skip to content

[Linux] REST + WebSocket client #132

@2witstudios

Description

@2witstudios

Overview

Implement the HTTP REST client and WebSocket manager for communicating with ppg serve.

REST Client (client.rs)

Uses reqwest with Bearer token auth. All 13 endpoints consumed by the macOS app:

Method Path Returns
GET /api/status Full manifest JSON
GET /api/worktrees/:id Single worktree
GET /api/worktrees/:id/diff Git diff stats
GET /api/agents/:id/logs?lines=N Raw tmux capture
GET /api/config Session config
GET /api/templates Template file names
GET /api/prompts Prompt file names
GET /api/swarms Swarm names
POST /api/spawn Spawn worktree + agents
POST /api/agents/:id/send Send keys to agent
POST /api/agents/:id/kill Kill agent
POST /api/agents/:id/restart Restart agent
POST /api/worktrees/:id/merge Merge worktree
POST /api/worktrees/:id/kill Kill all agents
POST /api/worktrees/:id/pr Create GitHub PR

WebSocket Client (websocket.rs)

Uses tokio-tungstenite. Connects to /ws?token=<token>.

Server Events to Handle

  • manifest_updated → full manifest snapshot
  • agent_status_changed{ agentId, status }
  • worktree_status_changed{ worktreeId, status }
  • terminal:output{ agentId, data } (terminal streaming)
  • pong → heartbeat response
  • error{ code, message }

Client Commands to Send

  • { type: "ping" } — keepalive (every 30s)
  • { type: "subscribe", channel: "terminal:<agentId>" }
  • { type: "unsubscribe", channel: "terminal:<agentId>" }
  • { type: "terminal_input", agentId, data } — keyboard input relay

Reconnection

Exponential backoff: base 1s, max 30s. Track connection state (Disconnected/Connecting/Connected/Reconnecting(attempt)).

GTK Thread Integration

WebSocket runs on tokio runtime. Events dispatched to GTK main thread via glib::MainContext::channel:

let (tx, rx) = glib::MainContext::channel(glib::Priority::DEFAULT);
tokio::spawn(ws_loop(url, token, tx));
rx.attach(None, move |event| {
    // Update AppState on GTK main thread
    glib::ControlFlow::Continue
});

References

  • Server implementation: src/server/index.ts, src/server/routes/, src/server/ws/
  • iOS WebSocket: ios/PPGMobile/PPGMobile/Networking/WebSocketManager.swift
  • macOS WebSocket: PPG CLI/PPG CLI/WebSocketManager.swift

Acceptance Criteria

  • REST client connects and fetches manifest successfully
  • WebSocket connects with token auth
  • Reconnection works with exponential backoff
  • Events dispatched to GTK main thread correctly
  • Terminal subscribe/unsubscribe/output events work
  • Ping keepalive at 30s interval

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions