# Veskslop daemon The external daemon and the development spikes. The daemon holds all logic and exposes MCP. Read the project docs first: [../docs/INDEX.md](../docs/INDEX.md). ## Setup ```sh pnpm install ``` ## Run commands | Command | Purpose | | --- | --- | | `pnpm poc:qr` | QR login. Writes the token file. | | `pnpm control:bridge` | Start the daemon. MCP on `http://127.0.0.1:8788/mcp`, web UI on `http://0.0.0.0:8789/`. The web UI can start/stop the client and run QR login. | | `pnpm control:mock` | Start the mock core. Test the daemon without Electron. | | `pnpm test:trigger` | Inject a trigger event into the mock core. | | `pnpm poc:dm` | Send one test DM to zzib. | | `pnpm test:comm` | Run the unit tests for the pure logic. | | `pnpm test:cache` | Run the unit tests for the message cache. | | `pnpm cdp:probe` | Check CDP access and event delivery. | | `pnpm cdp:dispatch` | Run one CDP expression in the client. | | `pnpm check` | Type check the daemon code. | ## Transport The primary transport is the validated core bridge at `vesktop-puppet.sock`. The daemon sends validated actions and receives normalized events. See [../docs/core-bridge.md](../docs/core-bridge.md). The CDP transport is a development fallback. It needs no Vesktop patch, and it has no core-side guardrails. Use it for debugging only. ## Pacing Outbound sends use a human-emulation policy: the first send of a burst waits 30 to 200 ms, later sends wait 500 to 2800 ms, and a burst ends after a random 5 to 20 seconds of quiet. Read queries are serialized with a 100 to 300 ms gap and do not reset the burst. One queue serializes everything. The queue coalesces identical concurrent reads. State reads use the cache. `DEBUG=1` logs each command and its delay. See [../docs/daemon.md](../docs/daemon.md). ## Live test target The only permitted live-send target is user zzib. See [../docs/testing.md](../docs/testing.md) for the full setup. ## Verified - QR login works end-to-end. The token came from a phone scan. - The core bridge works live. `get_state` returned the real account and 7 guilds. `send_dm` reached zzib. A synthetic owner message reached the daemon log with the command parsed. - The mock path works. The daemon handles state, sends, commands, tiers, continuation, user search, voice state, context, and the action log. - The web UI API and the SSE stream work against the mock core. - The web UI follows the Nocturne design handoff (`WebUIMockup.zip`). The 7a shell, the locked/unlocked composer, the console drawer, and the Settings slide-over were verified by rendering the page headless in Electron under Xvfb. - Core process control works live: the web UI start spawned the client under auto-Xvfb, the bridge connected, `state.get` returned the real account and guilds, and stop exited with code 0. Electron needs `libasound2`; Xvfb is auto-started when `DISPLAY` is unset. - The QR login session reaches `pending` with a scannable QR against the real gateway, and cancels cleanly. A full approval was not run in this environment. - Pacing follows the burst policy: 30-200 ms for the first send, 500-2800 ms afterwards. Open live items: - `reaction.add` and the message ID return are mock-verified only. The first live run must confirm Discord's internal `addReaction` lookup. - `user.search`, `voice.overview`, and `VOICE_STATE_UPDATE` are mock-verified only. - Voice join, leave, and move are not implemented. ## Findings - Official `discord.js` is bot-only. It fails at login with a user token. The popular selfbot fork is archived. Do not use either. The core is the real Vesktop client. - MCP SDK `1.30.0` Streamable HTTP works as used here. - CDP gives control and events with no Vesktop patch. Raw CDP has no guardrails. The validated core bridge is the target for this reason. - pnpm 11: this folder is its own workspace root. Build approvals live in `pnpm-workspace.yaml` (`allowBuilds`).