Files
Veskslop-t/poc/README.md
T

98 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Veskslop Phase 0 spikes
Timeboxed proof-of-concept scripts, not production code. Project direction lives in
[../AGENTS.md](../AGENTS.md).
## Setup
```sh
pnpm install
```
## Current query policy
- Every command sent to the client is spaced by a random **500–2800 ms** and serialized through one
queue (`src/pacing.ts`).
- Identical concurrent reads are coalesced (`dedupe`), and state reads are cache-only.
- `DEBUG=1` logs every command and its delay.
## Spikes
### 0. QR login / token acquisition — `src/qr-login.ts`
```sh
pnpm poc:qr
TOKEN_FILE=/path/to/token DEBUG=1 pnpm poc:qr
```
Connects to `wss://remote-auth-gateway.discord.gg/?v=2`, renders the approval QR directly in the
terminal, waits for a phone scan, exchanges the login ticket and writes the token to
`poc/.token` (mode 600, gitignored; override with `TOKEN_FILE`). No existing token required.
If Discord responds with an hCaptcha challenge, the script prints the challenge and prompts for a
`HCAPTCHA_KEY` (or takes it from the environment).
### 1. Vesktop control bridge — `src/control-bridge.ts`
The MCP daemon. Exposes Streamable HTTP and forwards tool calls over the JSON-lines protocol on
Vesktop's control socket (default `$XDG_RUNTIME_DIR/vesktop.sock`, override with `VESKSLOP_SOCKET`).
```sh
pnpm control:bridge # http://127.0.0.1:8788/mcp
VESKSLOP_SOCKET=... MCP_PORT=... pnpm control:bridge
```
Tools: `get_state` (cache-only), `send_message`, `read_messages` (coalesced), `send_dm`.
Vesktop side lives in this repo:
- `src/main/ipcSocket.ts` — parses JSON lines `{ id, command, data }` and forwards them through
`sendRendererCommand`.
- `src/renderer/ipcCommands.ts` — handlers that use official client interactions (`sendMessage`,
`openPrivateChannel`, guild/channel/message stores).
Protocol commands: `ping`, `state:get`, `message:send`, `message:read`, `dm:send`.
### 2. Mock Vesktop — `src/mock-vesktop.ts`
```sh
VESKSLOP_SOCKET=/tmp/veskslop-mock.sock pnpm control:mock
```
Stands in for the real Vesktop process so the bridge can be developed without Electron/Xvfb.
### 3. Live DM test — `src/test-dm.ts`
```sh
TEST_DM_USER_ID=... pnpm poc:dm
```
Talks to a **real** running Vesktop's control socket and sends one paced DM. The only sanctioned
live-send target is user **zzib** (provide their user ID).
## Verified
- QR login works end-to-end; the token in `.token` came from a phone scan.
- MCP bridge path: `initialize`, `tools/list`, `get_state`, `send_message`, `read_messages`,
`send_dm` all round-trip correctly through the mock.
- Pacing observed live: consecutive commands reached the mock **592 ms**, **1862 ms** and
**1439 ms** apart — inside the 500–2800 ms window.
## Deferred (not testable in this container)
- Real renderer handlers against a live Discord session (needs Electron + display).
- Headless display strategy (Xvfb/offscreen) and client lightening.
- Token injection into the official client.
- Voice join/leave and audio/video pipelines (need a voice channel; ffmpeg/PipeWire absent).
- Remote client auth over LAN/Tailscale and the web debug UI.
## Findings
- Official `discord.js` is bot-only (`/gateway/bot` → 401 with a user token), and
`discord.js-selfbot-v13` is archived — do not build on either. The core is the real Vesktop
client, puppeted through its own interactions.
- MCP SDK `1.30.0` stateless Streamable HTTP works as used here.
- Vesktop's existing `sendRendererCommand`/`onIpcCommand` bus is enough to puppet interactions; the
socket only needed a JSON-lines framing and a command map.
- pnpm 11: this folder is its own workspace root; build approvals live in `pnpm-workspace.yaml`
(`allowBuilds`).