# Architecture ## Purpose Veskslop controls one or more Discord user accounts without a visible client window. It uses the real Vesktop client, so the traffic comes from the official client. ## Parts The system has four parts: 1. **Vesktop core** — the real Vesktop client. It runs headless. It exposes a small capability layer. 2. **Core bridge** — the capability layer. It accepts validated actions and pushes events. 3. **Veskslop daemon** — the external process. It holds all logic. It exposes MCP. 4. **MCP clients** — agents and tools. They call the daemon. ``` MCP clients (agents) │ Streamable HTTP (MCP) ▼ Veskslop daemon ──── JSON lines over a Unix socket ────▶ Vesktop core │ │ │ QR login, pacing, trigger log, │ validated actions + events │ trust list, MCP tools ▼ │ Discord (official client traffic) ▼ Local state files (.token, .veskslop-state.json) ``` ## Boundary rules The boundary is narrow on purpose. - The core exposes a fixed action list. The list has no general "run this code" action. - The core validates every input. Bad input returns a structured error. The client does not crash. - The core rate limits all outbound actions. A bug in the daemon cannot cause a send flood. - The daemon holds the logic: triggers, trust list, command parsing, the trigger log, and pacing. - The daemon holds no Discord protocol code. These rules keep upstream rebases small. Logic changes do not touch the core. The core changes only when the action list changes. ## Components and status | Component | Location | Status | | --- | --- | --- | | Action protocol | `src/shared/puppetProtocol.ts` | Implemented | | Validated actions | `src/renderer/puppet/actions.ts` | Implemented | | Event push | `src/renderer/puppet/events.ts` | Implemented | | Main bridge | `src/main/puppetBridge.ts` | Implemented | | Core hooks | `src/main/main.ts`, `src/renderer/ipcCommands.ts`, `src/shared/IpcEvents.ts`, `src/preload/VesktopNative.ts` | Implemented | | Daemon (core-bridge transport) | `poc/src/core-client.ts` | Implemented and verified live | | Daemon (CDP transport) | `poc/src/cdp-client.ts` | Kept as a development fallback | | QR login | `poc/src/qr-login.ts` | Implemented and verified live | | Pacing | `poc/src/pacing.ts` | Implemented | | Trigger log and trust list | `poc/src/communication.ts`, `poc/src/puppet.ts` | Implemented and verified live | | Voice, audio, video | Not started | Not started | ## Data flow 1. An agent calls an MCP tool on the daemon. 2. The daemon applies pacing and policy. 3. The daemon sends one JSON-line action to the core bridge. 4. The bridge forwards the action to the renderer. 5. The renderer validates the action and calls the official client. 6. The renderer returns a result or a structured error. 7. The bridge returns the response to the daemon. For inbound messages, the flow goes the other way: 1. The client receives a gateway event. 2. The renderer normalizes the event. 3. The bridge pushes the event to subscribed daemon connections. 4. The daemon applies the trigger rules and updates the log.