Add headless puppet bridge: control socket, renderer handlers, MCP daemon
This commit is contained in:
@@ -2,76 +2,93 @@
|
||||
|
||||
## What this is
|
||||
|
||||
Veskslop is a **headless Discord client daemon** built on the Vesktop codebase. It turns one or
|
||||
more **Discord user accounts** into a controllable service:
|
||||
Veskslop is a **headless Discord client daemon** built on the Vesktop codebase. It runs the **real
|
||||
Discord web client** (Vencord-patched Vesktop) without a visible window and puppets the client's own
|
||||
interactions, so traffic and behavior stay as close to the official client as possible.
|
||||
|
||||
- an **MCP server** (Streamable HTTP) lets AI agents drive a "puppet" account;
|
||||
- a second, read-only account can collect stats/data without acting;
|
||||
- **audio is piped in and out** over PipeWire;
|
||||
- **video streams** can be pushed into voice channels;
|
||||
- an **MCP server** (Streamable HTTP) lets AI agents drive the account;
|
||||
- multiple user identities are planned (one read-only collector, one full puppet);
|
||||
- **audio in/out** and **video streaming** come later, using the client's native voice stack
|
||||
plus PipeWire virtual devices on Linux;
|
||||
- everything is **local-first**: clients reach it over LAN/Tailscale only.
|
||||
|
||||
**Vesktop is a separate project with separate goals.** This repo shares history with it but not
|
||||
direction. Do not carry Vesktop UI features here unless the daemon needs them.
|
||||
direction.
|
||||
|
||||
## Decisions (locked unless the user changes them)
|
||||
|
||||
- **Core:** TypeScript on Node with pnpm. `discord.js` for gateway/REST, `@discordjs/voice` for voice.
|
||||
- **Core:** run the actual Vesktop/Discord client (Electron) headless. Do **not** build on
|
||||
third-party selfbot protocol libraries — the popular ones are archived/deprecated and stale
|
||||
protocol emulation is a ban risk.
|
||||
- **Control:** puppet Vesktop's own interactions through its IPC command bus:
|
||||
`vesktop.sock` (external) → `sendRendererCommand` (main) → renderer handlers that call
|
||||
Vencord/Discord internals (`sendMessage`, stores, voice actions).
|
||||
- **MCP:** an external local daemon speaks a JSON-lines protocol over `vesktop.sock` and exposes
|
||||
Streamable HTTP MCP. It must run without Electron so it is testable standalone.
|
||||
- **QR login:** our own terminal remote-auth tool (`poc/qr-login.ts`) acquires a user token.
|
||||
Feeding that token into the headless client is deferred until it can be tested.
|
||||
- **Accounts:** multiple user tokens. Expected setup is one read-only collector account plus one
|
||||
full-control puppet account; design for N identities behind one control surface.
|
||||
- **MCP transport:** Streamable HTTP only (no stdio/SSE unless asked).
|
||||
- **Network:** bind localhost by default. Remote access is always over LAN/Tailscale — never expose
|
||||
to the public internet. A client will later authenticate to the proxy for remote control.
|
||||
- **Audio:** PipeWire only.
|
||||
- **GUI:** optional minimal **web debug UI** if it is cheap to build; otherwise keep the existing
|
||||
Vesktop Electron build runnable for debugging. The daemon must never require Electron.
|
||||
- **Pacing/safety:** actions emulate a human using the Vesktop client through a queue:
|
||||
- first action is snappy (~30–80 ms delay);
|
||||
- subsequent bulk actions get randomized delays (~500–2800 ms);
|
||||
- a **risky fast mode** is opt-in and minimizes delays;
|
||||
- default capabilities are clamped to free-account limits (upload size, stream resolution, etc.);
|
||||
- individual abilities can be toggled off.
|
||||
- **Audio/video:** use the client's native stack first; PipeWire virtual devices for system audio
|
||||
piping. ffmpeg is required for non-Opus media and video encoding.
|
||||
- **GUI:** optional minimal **web debug UI** later. The daemon must never require a visible window;
|
||||
on servers without a display, a virtual display (Xvfb) will be needed for Electron.
|
||||
- **Pacing/safety:** all outbound actions are queued and paced.
|
||||
- **Current policy:** every command sent to the client is spaced by a random **500–2800 ms**,
|
||||
serialized, with identical in-flight queries coalesced; prefer cached state over queries.
|
||||
- **Later policy:** human emulation — snappy first action (~30–80 ms), bulk actions randomized,
|
||||
opt-in risky fast mode, free-account limits by default, ability toggles.
|
||||
|
||||
## How to proceed
|
||||
|
||||
**Phase 0 — PoC, do this first.** Find the smallest end-to-end thing that works, then stop and
|
||||
report back so the user can choose a direction. Candidate spikes, timeboxed:
|
||||
**Current milestone — puppeting bridge (testable without Electron).**
|
||||
|
||||
1. `discord.js` login + list guilds + send a message from a throwaway test account.
|
||||
2. Minimal MCP Streamable HTTP server exposing `send_message` / `read_messages`, wired to #1.
|
||||
3. Join a voice channel and play a local file via `@discordjs/voice` (PipeWire output).
|
||||
1. Extend Vesktop's `vesktop.sock` server with a JSON-lines request/response protocol (keep the
|
||||
legacy `run-shortcut` line working).
|
||||
2. Add renderer handlers for `state:get`, `message:send`, `message:read` via Vencord internals.
|
||||
3. Build the external MCP daemon (`poc/src/control-bridge.ts`) with a mock Vesktop socket
|
||||
(`poc/src/mock-vesktop.ts`) so the whole path is testable in this container.
|
||||
4. Then: voice join/leave handlers, audio pipes, video streaming, token injection, client
|
||||
lightening, remote client auth.
|
||||
|
||||
Prefer whichever is quickest to prove; do not build production architecture before the user picks.
|
||||
|
||||
**After regrouping:** headless daemon skeleton → multi-account session manager → pacing queue →
|
||||
MCP tool surface → audio pipelines → video pipeline → remote proxy/auth client → web debug UI.
|
||||
Anything that needs a display, audio device, or a real client instance is **deferred** until it can
|
||||
be tested; note it instead of guessing.
|
||||
|
||||
## Architecture sketch
|
||||
|
||||
```
|
||||
MCP clients (agents) ──Streamable HTTP──▶ Veskslop core ──▶ Discord (user tokens)
|
||||
remote web client ─────auth over LAN─────▶ │
|
||||
├─ action queue (human-emulation pacing)
|
||||
├─ capability policy + limits + audit log
|
||||
├─ audio pipeline (PipeWire)
|
||||
└─ video pipeline
|
||||
MCP clients (agents) ──Streamable HTTP──▶ veskSlop control daemon
|
||||
│ JSON lines over vesktop.sock
|
||||
▼
|
||||
Vesktop main process
|
||||
│ sendRendererCommand()
|
||||
▼
|
||||
Discord renderer (Vencord patched)
|
||||
│ official client actions
|
||||
▼
|
||||
Discord
|
||||
```
|
||||
|
||||
## Guardrails for agents working here
|
||||
|
||||
- **Never commit tokens, credentials, or `.env` files.** Use environment variables / a local secret store.
|
||||
- Do not adopt archived/deprecated selfbot libraries. If a library is needed, verify it was pushed
|
||||
recently before proposing it.
|
||||
- Do not hardcode Discord limits from memory — verify current free-tier numbers (upload size, stream
|
||||
resolution, rate limits) at implementation time, and keep them configurable.
|
||||
- All outbound actions go through the pacing queue; no direct sends.
|
||||
- Default to conservative limits and opt-in risky features.
|
||||
- Test against throwaway accounts and private test guilds only.
|
||||
- **Live send tests:** DMs to user **zzib** are the only sanctioned real-send test target.
|
||||
- Run `pnpm testTypes` and `pnpm lint` before calling work done; `pnpm build` to compile.
|
||||
|
||||
## Open questions
|
||||
|
||||
- Which Phase 0 spike becomes the real foundation? (user decides after the spikes)
|
||||
- Voice E2EE (DAVE) support status in the current voice stack — research before committing.
|
||||
- Video pipeline feasibility: required codecs/containers and how to feed synthetic frames.
|
||||
- Headless Electron strategy: Xvfb vs offscreen rendering, and what to strip to lighten the client.
|
||||
- Token injection path for the official client (localStorage seeding vs client QR UI).
|
||||
- Voice/video: what the client's native stack can be driven to do without UI interaction.
|
||||
- Scope and auth model of the future remote proxy client and web debug UI.
|
||||
- How much of the Vesktop Electron tree gets deleted once the daemon is self-sufficient.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user