-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Overview
Implement C# models mirroring the ppg manifest JSON, plus HTTP REST and WebSocket clients for ppg serve.
Data Models (Models/)
Manifest.cs
public record Manifest(
[property: JsonPropertyName("version")] int Version,
[property: JsonPropertyName("projectRoot")] string ProjectRoot,
[property: JsonPropertyName("sessionName")] string SessionName,
[property: JsonPropertyName("worktrees")] Dictionary<string, WorktreeEntry> Worktrees,
[property: JsonPropertyName("createdAt")] string CreatedAt,
[property: JsonPropertyName("updatedAt")] string UpdatedAt
);
public record WorktreeEntry(
string Id, string Name, string Path, string Branch,
[property: JsonPropertyName("baseBranch")] string BaseBranch,
WorktreeStatus Status,
[property: JsonPropertyName("tmuxWindow")] string TmuxWindow,
[property: JsonPropertyName("prUrl")] string? PrUrl,
Dictionary<string, AgentEntry> Agents,
[property: JsonPropertyName("createdAt")] string CreatedAt,
[property: JsonPropertyName("mergedAt")] string? MergedAt
);
// ... AgentEntry, AgentStatus, WorktreeStatus enumsHandle status aliases in JSON deserialization: idle → Running, exited → Completed, gone → Lost.
AgentVariant.cs
Match macOS AgentVariant.swift: Claude, Codex, OpenCode, Terminal, Worktree with display names, icons, and prompt delivery methods.
REST Client (Services/PpgApiClient.cs)
HttpClient with Bearer token auth. Same 13+ endpoints as Linux issue #132.
public class PpgApiClient
{
private readonly HttpClient _http;
public async Task<Manifest> GetStatusAsync() =>
await GetAsync<Manifest>("/api/status");
public async Task SpawnAsync(SpawnRequest request) =>
await PostAsync("/api/spawn", request);
// ... all 13 endpoints
}WebSocket Client (Services/WebSocketClient.cs)
System.Net.WebSockets.ClientWebSocket with:
- Token auth via query param (
/ws?token=...) - Exponential backoff reconnect (1s base, 30s max)
- 30s ping keepalive via
Task.Delay - Event dispatch to UI thread via
Dispatcher.InvokeAsync - Same events as Linux issue [Linux] REST + WebSocket client #132
public class WebSocketClient
{
public event Action<Manifest>? ManifestUpdated;
public event Action<string, AgentStatus>? AgentStatusChanged;
public event Action<string, string>? TerminalOutput; // agentId, data
public async Task ConnectAsync(string url, string token, CancellationToken ct);
public async Task SubscribeTerminalAsync(string agentId);
public async Task UnsubscribeTerminalAsync(string agentId);
public async Task SendTerminalInputAsync(string agentId, string data);
}ManifestStore (Services/ManifestStore.cs)
Observable singleton that holds the current manifest and raises PropertyChanged on updates:
public partial class ManifestStore : ObservableObject
{
[ObservableProperty] private Manifest? _manifest;
[ObservableProperty] private ConnectionState _state;
// Updated by WebSocketClient events or REST polling
}Token Storage (Services/TokenStorage.cs)
Use System.Security.Cryptography.ProtectedData (DPAPI) to encrypt bearer tokens at rest.
Store in %APPDATA%/PPG Desktop/credentials.dat.
References
- Server API:
src/server/index.ts,src/server/routes/,src/server/ws/ - Manifest types:
src/types/manifest.ts
Acceptance Criteria
- All manifest types deserialize correctly from ppg serve JSON
- REST client connects and fetches status
- WebSocket connects, reconnects, dispatches events to UI thread
- Terminal subscribe/output streaming works
- Token stored securely with DPAPI
- Unit tests for JSON deserialization
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request