docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev, server-release) is actually for, and how to build voicecat-server + vccli for manual testing. Linked from CLAUDE.md's doc index. - core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h, server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do", protobuf codegen "commented") that M1-M3 made real. Updated to describe current behavior, with the dev-preset stub fallback noted explicitly where it still applies.
This commit is contained in:
@@ -121,6 +121,7 @@ Read [`docs/`](docs/) before changing behavior. Order:
|
||||
6. [docs/tech-stack.md](docs/tech-stack.md) — libraries, permissive-license rule, tooling
|
||||
7. [docs/deployment.md](docs/deployment.md) — zero-config self-host (Docker / binary / source)
|
||||
8. [docs/roadmap.md](docs/roadmap.md) — milestones + resolved decisions
|
||||
9. [docs/building.md](docs/building.md) — what each CMake preset is for + manual server/`vccli` testing
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -8,8 +8,13 @@
|
||||
* Design: docs/architecture.md §4. Everything here is async + event-driven — calls return
|
||||
* immediately and results/state changes arrive via the vc_callbacks.on_event callback.
|
||||
*
|
||||
* STATUS: M0 skeleton. Implementations live in core/src and currently return
|
||||
* VC_ERR_NOT_IMPLEMENTED. The shapes below are the contract to build against.
|
||||
* STATUS: real, behind VOICECAT_HAS_NET (the `m1-dev`/`server-release` presets — vcpkg deps
|
||||
* on; see docs/building.md). As of M3, control plane, voice, multi-stream, device
|
||||
* enumeration, VAD/PTT, and stereo playback all work for real via core/src/core/client.cpp.
|
||||
* The no-deps `dev` preset still links a stub vc_client that returns VC_ERR_NOT_IMPLEMENTED
|
||||
* for everything below `connect`, purely to keep that skeleton build green. webrtc AEC/NS/AGC
|
||||
* remains an inert passthrough regardless of preset (no Windows/MSVC port upstream —
|
||||
* docs/voice.md §8/§11, PROGRESS.md).
|
||||
*/
|
||||
#ifndef VOICECAT_H
|
||||
#define VOICECAT_H
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
* request_id ↔ response, and dispatches to handlers. Media frames do NOT come through here
|
||||
* (they use the fixed binary header in voice.md §2).
|
||||
*
|
||||
* STATUS: M0 stub — protobuf codegen is wired in CMake (commented) and turned on in M1.
|
||||
* STATUS: real. Protobuf codegen is on (core/CMakeLists.txt) for VOICECAT_HAS_NET builds
|
||||
* (`m1-dev`/`server-release`); FrameCodec below is fully implemented and used by both the
|
||||
* client (net/transport.h) and the server (conn_session.cpp). See protocol/envelope.h for the
|
||||
* Envelope-level encode/decode that sits on top of this.
|
||||
*/
|
||||
#ifndef VOICECAT_PROTOCOL_PROTOCOL_H
|
||||
#define VOICECAT_PROTOCOL_PROTOCOL_H
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*
|
||||
* voicecat.cpp — C ABI implementation (M0 skeleton).
|
||||
* voicecat.cpp — C ABI implementation.
|
||||
*
|
||||
* Lifecycle (create/destroy) and trivial accessors are real. Everything that needs a
|
||||
* subsystem (net/crypto/codec/protocol/session/audio) returns VC_ERR_NOT_IMPLEMENTED for
|
||||
* now and is the work of M1+ (see AGENTS.md / docs/roadmap.md).
|
||||
* Lifecycle (create/destroy) and trivial accessors are always real. Everything else below
|
||||
* just delegates to vc_client (core/src/core/client.cpp): under VOICECAT_HAS_NET
|
||||
* (`m1-dev`/`server-release` — see docs/building.md) that's the real M1–M3 implementation;
|
||||
* under the no-deps `dev` preset, client.cpp's `#else` branch returns VC_ERR_NOT_IMPLEMENTED
|
||||
* for all of it, to keep that skeleton build green.
|
||||
*/
|
||||
#include "voicecat.h"
|
||||
|
||||
@@ -48,7 +50,7 @@ vc_client* vc_client_create(const vc_config* cfg, vc_callbacks cb) {
|
||||
|
||||
void vc_client_destroy(vc_client* c) { delete c; }
|
||||
|
||||
/* ── Everything below delegates to the (stub) client. ─────────────────────── */
|
||||
/* ── Everything below delegates to vc_client (real or stub, per preset above). ───────── */
|
||||
|
||||
vc_result vc_connect(vc_client* c, const char* host, uint16_t port) {
|
||||
if (c == nullptr || host == nullptr) return VC_ERR_INVALID_ARG;
|
||||
|
||||
152
docs/building.md
Normal file
152
docs/building.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Building & Manual Testing
|
||||
|
||||
This doc explains what each CMake preset in [`CMakePresets.json`](../CMakePresets.json) is
|
||||
*for*, which one to actually use day-to-day, and the commands to stand up a real server +
|
||||
`vccli` clients against each other for manual testing. For the one-paragraph quick-start see
|
||||
[`CLAUDE.md`](../CLAUDE.md); for `ctest` targets see [`AGENTS.md`](../AGENTS.md). This doc is
|
||||
the missing middle: *how the presets relate to each other*, and *how to drive the binaries by
|
||||
hand*.
|
||||
|
||||
## 1. What each preset is for
|
||||
|
||||
| Preset | Binary dir | Deps | What it's actually for |
|
||||
|--------|-----------|------|-------------------------|
|
||||
| `dev` | `build/dev` | none (`VOICECAT_USE_VCPKG_DEPS=OFF`) | The M0 skeleton. Compiles with just a C++20 compiler — no `VCPKG_ROOT` needed. Subsystems are stubs (`VC_ERR_NOT_IMPLEMENTED`). Good for "does the repo even build" sanity checks, not for testing real voice/control behavior. |
|
||||
| `vcpkg-base` | — | real deps via vcpkg | Hidden base preset, not used directly. Requires `VCPKG_ROOT` in the environment; every preset below inherits it. |
|
||||
| `m1-dev` | `build/m1-dev` | real deps | **The one you actually want.** Despite the name, this is the live development preset for everything from M1 onward — M1, M2, and M3 were all built, tested, and manually verified against `build/m1-dev` (see `PROGRESS.md`). Builds tools + tests. |
|
||||
| `m2-dev` | `build/m2-dev` | real deps | Cache-identical to `m1-dev` (same `VOICECAT_BUILD_TOOLS=ON`, `VOICECAT_BUILD_TESTS=ON`, same triplet) — the only difference is the binary dir. It exists from when the project briefly split a preset per milestone; that convention was dropped in practice. Use it only if you want a second, isolated build tree (e.g. to compare two branches) — there's no behavioral reason to prefer it over `m1-dev`. |
|
||||
| *(no `m3-dev`)* | — | — | M3 work used `m1-dev` directly; no separate preset was ever added for it. If you see `m3-dev` mentioned anywhere, it doesn't exist — use `m1-dev`. |
|
||||
| `server-release` | `build/server-release` | real deps, `Release` | Production-shaped build (docs/deployment.md "from source" path): `CMAKE_BUILD_TYPE=Release`, tools on, **tests off**. This is what you'd actually ship/run, not what you iterate against. |
|
||||
|
||||
So in practice there are really only two presets that matter:
|
||||
- **`dev`** — fast no-deps build to confirm the skeleton compiles.
|
||||
- **`m1-dev`** — everything else: real protocol, real voice, real manual testing.
|
||||
|
||||
## 2. One-time setup for the real-deps presets
|
||||
|
||||
`m1-dev`, `m2-dev`, and `server-release` all need `VCPKG_ROOT` pointing at a bootstrapped
|
||||
vcpkg checkout:
|
||||
|
||||
```bash
|
||||
# once:
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
./vcpkg/bootstrap-vcpkg.sh # .bat on Windows
|
||||
|
||||
# every shell session (PowerShell):
|
||||
$env:VCPKG_ROOT = "D:\path\to\vcpkg"
|
||||
```
|
||||
|
||||
`vcpkg.json` (manifest mode) pins every dependency (protobuf, mbedTLS, libsodium, asio,
|
||||
sqlite3, spdlog, opus, miniaudio) — `cmake --preset m1-dev` resolves and builds them
|
||||
automatically on first configure. That first configure is slow (vcpkg building from source);
|
||||
subsequent ones are cached.
|
||||
|
||||
## 3. Build + test (the loop you'll run constantly)
|
||||
|
||||
```bash
|
||||
cmake --preset m1-dev
|
||||
cmake --build --preset m1-dev
|
||||
ctest --test-dir build/m1-dev --output-on-failure
|
||||
```
|
||||
|
||||
(`ctest --preset m1-dev` is equivalent — both are wired up in `CMakePresets.json`.) Binaries
|
||||
land in `build/m1-dev/bin/` (`.exe` suffix on Windows):
|
||||
|
||||
- `build/m1-dev/bin/voicecat-server`
|
||||
- `build/m1-dev/bin/vccli`
|
||||
- `build/m1-dev/bin/voicecat-admin`
|
||||
|
||||
## 4. Manual testing: server + two clients
|
||||
|
||||
### Start the server
|
||||
|
||||
```bash
|
||||
./build/m1-dev/bin/voicecat-server --name "Test Server" --data-dir ./voicecat-data
|
||||
```
|
||||
|
||||
First run generates an Ed25519 identity + self-signed cert under `--data-dir`, creates the
|
||||
SQLite store, and creates a default "Lobby" channel. Other server flags:
|
||||
|
||||
```
|
||||
--port <n> control+media port (default 8384)
|
||||
--data-dir <path> data directory (default ./voicecat-data)
|
||||
--name <name> server name
|
||||
--no-guests disable guest access (then provision accounts via voicecat-admin)
|
||||
--print-config print effective config and exit
|
||||
--version print version and exit
|
||||
```
|
||||
|
||||
### Drive it with `vccli`
|
||||
|
||||
`vccli` is the headless client used to exercise the protocol by hand. Full flag list:
|
||||
|
||||
```
|
||||
vccli [--host H] [--port P] [--nick NAME] [--channel ID]
|
||||
[--voice] [--mute] [--text MSG] [--list-devices]
|
||||
[--input-device ID] [--input-mode vad|ptt] [--share-screen-audio]
|
||||
|
||||
--host H server host (default 127.0.0.1)
|
||||
--port P server TCP port (default 8384)
|
||||
--nick NAME guest nickname (default vccli-test)
|
||||
--channel ID channel to join after auth (default 1, Lobby)
|
||||
--voice start a MIC stream and stay connected until Ctrl+C
|
||||
--mute start with the mic muted (only meaningful with --voice)
|
||||
--text MSG send MSG to the channel, then exit
|
||||
--list-devices print input/output devices (vc_list_devices) and exit
|
||||
--input-device ID use device ID (from --list-devices) for the MIC stream
|
||||
--input-mode vad|ptt send-side input gate mode (default vad)
|
||||
--share-screen-audio also start a SCREEN_AUDIO stream (WASAPI loopback on Windows)
|
||||
```
|
||||
|
||||
While `--voice` is running, stdin accepts `ptt on`, `ptt off`, `mode vad`, `mode ptt` to
|
||||
toggle the input gate live.
|
||||
|
||||
**Smoke test — two clients talking:**
|
||||
|
||||
```bash
|
||||
# terminal A
|
||||
./build/m1-dev/bin/vccli --nick Alice --text "hello from Alice"
|
||||
|
||||
# terminal B (separate window, after A confirms it sent)
|
||||
./build/m1-dev/bin/vccli --nick Bob --text "hello from Bob"
|
||||
```
|
||||
|
||||
**Real voice between two clients (needs working mic/speakers, two terminals):**
|
||||
|
||||
```bash
|
||||
# terminal A
|
||||
./build/m1-dev/bin/vccli --nick Alice --voice
|
||||
|
||||
# terminal B
|
||||
./build/m1-dev/bin/vccli --nick Bob --voice
|
||||
```
|
||||
|
||||
Speak into the mic on one side; you should hear it on the other. Ctrl+C to disconnect.
|
||||
|
||||
**Enumerate audio devices before picking one:**
|
||||
|
||||
```bash
|
||||
./build/m1-dev/bin/vccli --list-devices
|
||||
./build/m1-dev/bin/vccli --nick Alice --voice --input-device <ID> --input-mode ptt
|
||||
```
|
||||
|
||||
**Provisioning a non-guest account** (if the server was started with `--no-guests`):
|
||||
|
||||
```bash
|
||||
./build/m1-dev/bin/voicecat-admin --data-dir ./voicecat-data account add alice --password secret
|
||||
./build/m1-dev/bin/voicecat-admin --data-dir ./voicecat-data account list
|
||||
```
|
||||
|
||||
## 5. `server-release` (production-shaped build)
|
||||
|
||||
Same dependency story, but `Release` build type and no tests — this is the closest local
|
||||
analogue to what `docs/deployment.md`'s "from source" path produces:
|
||||
|
||||
```bash
|
||||
cmake --preset server-release
|
||||
cmake --build --preset server-release
|
||||
./build/server-release/bin/voicecat-server
|
||||
```
|
||||
|
||||
Use this to sanity-check release-mode behavior (e.g. perf, optimized codepaths) — not for
|
||||
day-to-day development, since it has no test target wired up.
|
||||
@@ -1,8 +1,10 @@
|
||||
/*
|
||||
* voicecat-server entry point (M0 skeleton).
|
||||
* voicecat-server entry point.
|
||||
*
|
||||
* Goal (docs/deployment.md): one command, zero config, encrypted + listening. Today it
|
||||
* parses a few flags and prints what it would do.
|
||||
* Goal (docs/deployment.md): one command, zero config, encrypted + listening. Parses flags
|
||||
* (see docs/building.md for the full list + manual-testing walkthrough) and hands off to
|
||||
* Server::run() (server.cpp), which really does generate the identity/cert, open the SQLite
|
||||
* store, and bind the TCP/TLS + UDP listeners.
|
||||
*/
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
Reference in New Issue
Block a user