# Code Generators (qpq-gen)

The `qpq-gen` CLI tool scaffolds new plugins, bots, RPC methods, and hook
events for the quicproquo ecosystem.

## Installation

```bash
cargo install --path crates/quicproquo-gen
```

Or run directly from the workspace:

```bash
cargo run -p quicproquo-gen -- <subcommand>
```

## Subcommands

### `qpq-gen plugin <name>` -- Server Plugin

Scaffolds a standalone Cargo project for a server plugin compiled as a shared
library (`cdylib`). The generated plugin implements the `HookVTable` C ABI
and is loaded by the server at startup via `--plugin-dir`.

```bash
qpq-gen plugin rate-limiter
qpq-gen plugin audit-log --output /tmp/plugins
```

**Generated files:**

```
rate_limiter/
  Cargo.toml        # cdylib crate depending on quicproquo-plugin-api
  README.md         # Build and install instructions
  src/lib.rs        # Plugin skeleton with qpq_plugin_init entry point
```

The template includes:
- `qpq_plugin_init` -- called by the server on load; populates the `HookVTable`
- `on_message_enqueue` -- sample hook that rejects payloads larger than 1 MB
- `error_message` -- returns the rejection reason as a C string
- `destroy` -- frees the plugin state

**What to customize:** Replace the `on_message_enqueue` logic with your own
policy. Add more hooks by setting additional fields on the `HookVTable`
(`on_auth`, `on_channel_created`, `on_fetch`, `on_user_registered`,
`on_batch_enqueue`).

**Build and install:**

```bash
cd rate_limiter
cargo build --release
cp target/release/librate_limiter.so /path/to/plugins/
qpq-server --plugin-dir /path/to/plugins/
```

### `qpq-gen bot <name>` -- Bot Project

Scaffolds a standalone bot project using the Bot SDK. The generated binary
connects to a quicproquo server, authenticates via OPAQUE, and runs a
message-handling loop.

```bash
qpq-gen bot echo-bot
qpq-gen bot moderation-bot --output /tmp/bots
```

**Generated files:**

```
moderation_bot/
  Cargo.toml        # Binary crate depending on quicproquo-bot + tokio
  README.md         # Quick-start and command reference
  src/main.rs       # Bot skeleton with handle_message dispatcher
```

The template ships with four built-in commands as examples:

| Command         | Description               |
|-----------------|---------------------------|
| `!help`         | List available commands   |
| `!echo <text>`  | Echo back the text        |
| `!whoami`       | Show the sender's username|
| `!ping`         | Respond with "pong!"      |

**Configuration** is read from environment variables:

| Variable          | Default              |
|-------------------|----------------------|
| `QPQ_SERVER`      | `127.0.0.1:7000`     |
| `QPQ_USERNAME`    | `<bot-name>`         |
| `QPQ_PASSWORD`    | `changeme`           |
| `QPQ_CA_CERT`     | `server-cert.der`    |
| `QPQ_STATE_PATH`  | `<bot-name>-state.bin` |

**What to customize:** Edit the `handle_message` function in `src/main.rs`
to add your own command handlers. Return `Some(response)` to reply, or
`None` to stay silent.

**Run:**

```bash
cd moderation_bot
QPQ_SERVER=127.0.0.1:7000 \
QPQ_USERNAME=moderation_bot \
QPQ_PASSWORD=changeme \
QPQ_CA_CERT=path/to/server-cert.der \
cargo run
```

### `qpq-gen rpc <Name>` -- RPC Method Guide

Prints a step-by-step guide for adding a new Cap'n Proto RPC method to the
server. This generator does not create files; it outputs instructions and
code snippets to copy into the appropriate locations.

```bash
qpq-gen rpc listChannels
```

The `Name` argument should be in camelCase (e.g., `listChannels`). The
generator derives the `snake_case` form automatically for file and function
names.

**Steps covered:**

1. **Schema** -- Add the method to the `interface NodeService` block in
   `schemas/node.capnp`, then rebuild with `cargo build -p quicproquo-proto`
2. **Handler module** -- Create
   `crates/quicproquo-server/src/node_service/<name>.rs` with the handler
   implementation (template code is printed)
3. **Registration** -- Wire the handler into `node_service/mod.rs`
4. **Storage** (if needed) -- Add a method to the `Store` trait and implement
   it in `sql_store.rs` and `storage.rs`
5. **Hook** (optional) -- Run `qpq-gen hook <name>` to let plugins observe
   the new RPC
6. **Verify** -- `cargo build -p quicproquo-server && cargo test -p quicproquo-server`

### `qpq-gen hook <name>` -- Hook Event Guide

Prints a step-by-step guide for adding a new server hook event that plugins
can observe. Like `rpc`, this generator outputs instructions rather than
creating files.

```bash
qpq-gen hook message_deleted
```

The `name` argument should be in `snake_case` (e.g., `message_deleted`). The
generator derives the `PascalCase` form for struct names.

**Steps covered:**

1. **Event struct** -- Define `MessageDeletedEvent` in
   `crates/quicproquo-server/src/hooks.rs`
2. **Trait method** -- Add `on_message_deleted` to the `ServerHooks` trait
   with a default no-op implementation
3. **Tracing** -- Implement the hook in `TracingHooks` with a `tracing::info!`
   call
4. **Plugin API** -- Add a C-compatible `CMessageDeletedEvent` struct and an
   `on_message_deleted` field to `HookVTable` in
   `crates/quicproquo-plugin-api/src/lib.rs`
5. **Plugin dispatch** -- Wire the conversion and dispatch in
   `plugin_loader.rs`
6. **Call site** -- Fire the hook from the relevant RPC handler in
   `node_service/`
7. **Verify** -- Build and test `quicproquo-plugin-api` and
   `quicproquo-server`
