# aev-bridge
`aev-bridge` is the Aev bridge plugin crate from Trevor Knott / Knott Dynamics. It exposes a phone-friendly HTTP and Server-Sent Events interface that proxies to `aev-web`.
`aev-bridge` intentionally does not own PTYs or spawn terminal processes. `aev-web` owns terminal sessions, and `aev-bridge` focuses on safe LAN/mobile access and streaming output to browser clients.
## Package
- Crate: `aev-bridge`
- Binary: `aev-bridge`
- Plugin ID: `aev-bridge`
- Plugin entrypoint: `aev_plugin_init`
- Protocol: `aev.plugin.v1`
- Author: Trevor Knott
- Organization: Knott Dynamics
- Repository: `https://github.com/Tknott95/AevBridge`
## What It Does
- Binds a phone-accessible bridge server, default `0.0.0.0:8780`.
- Requires a bridge token for browser/API access.
- Proxies session creation, input, listing, and termination to `aev-web`.
- Streams terminal output over Server-Sent Events at `/api/sessions/{id}/events`.
- Accepts query-token auth for SSE because browser `EventSource` cannot set authorization headers.
- Prints a LAN URL when it can detect one.
- Exposes an Aev plugin manifest at `/api/manifest`.
## Install
From crates.io:
```bash
cargo install aev-bridge
```
From source:
```bash
git clone https://github.com/Tknott95/AevBridge.git
cd AevBridge
cargo run
```
## Quick Start
Start `aev-web` first:
```bash
AEV_WEB_TOKEN=replace-with-a-secret aev-web
```
Start the bridge with the same upstream token and a phone token:
```bash
AEV_WEB_TOKEN=replace-with-a-secret AEV_BRIDGE_TOKEN=phone-secret aev-bridge
```
The bridge prints a URL like:
```text
phone URL: http://192.168.1.50:8780/?token=phone-secret
```
Open that URL from a phone on the same LAN.
## Configuration
| Bridge bind address | `--bind` | `AEV_BRIDGE_BIND` | `0.0.0.0:8780` |
| Bridge browser/API token | `--token` | `AEV_BRIDGE_TOKEN` | generated UUIDv7 token |
| Upstream `aev-web` URL | `--upstream` | `AEV_BRIDGE_UPSTREAM` | `http://127.0.0.1:8765` |
| Upstream `aev-web` token | `--upstream-token` | `AEV_WEB_TOKEN` | required |
| Printed external URL | `--public-url` | `AEV_BRIDGE_PUBLIC_URL` | detected LAN URL |
| Output poll interval | `--poll-ms` | `AEV_BRIDGE_POLL_MS` | `300` |
Use `--bind 127.0.0.1:8780` if you only need local browser access and do not want LAN exposure.
## HTTP API
Public health endpoint:
```bash
curl http://127.0.0.1:8780/health
```
Authenticated fetch requests use `Authorization: Bearer <bridge-token>`.
Create a terminal session through the bridge:
```bash
curl -sS -X POST http://127.0.0.1:8780/api/sessions \
-H "Authorization: Bearer $AEV_BRIDGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
Write terminal input:
```bash
curl -sS -X POST http://127.0.0.1:8780/api/sessions/$SESSION_ID/input \
-H "Authorization: Bearer $AEV_BRIDGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":"pwd\r"}'
```
Stream terminal output from JavaScript:
```javascript
const events = new EventSource(`/api/sessions/${sessionId}/events?token=${bridgeToken}`)
events.addEventListener("output", (event) => {
const output = JSON.parse(event.data)
console.log(output.data)
})
```
Terminate a session:
```bash
curl -sS -X DELETE http://127.0.0.1:8780/api/sessions/$SESSION_ID \
-H "Authorization: Bearer $AEV_BRIDGE_TOKEN"
```
## API Routes
- `GET /health` returns public bridge health.
- `GET /api/manifest` returns the `aev-bridge` plugin manifest.
- `GET /api/upstream/health` checks the configured `aev-web` upstream.
- `GET /api/sessions` proxies active session listing.
- `POST /api/sessions` proxies session creation.
- `GET /api/sessions/{id}` proxies one session summary.
- `GET /api/sessions/{id}/events` streams output as SSE.
- `POST /api/sessions/{id}/input` proxies terminal input.
- `DELETE /api/sessions/{id}` terminates the upstream session.
## Aev Registration
The current Aev plugin board validates descriptors and contracts. It does not load plugin code yet. Register the descriptor with:
```text
/plugins add aev-bridge git https://github.com/Tknott95/AevBridge.git aev_plugin_init tool,bridge,mobile,http,sse,bearer-auth
/plugins validate all
```
See `examples/plugins.json` for an equivalent `.aev/plugins.json` entry.
## Security
- Treat `AEV_BRIDGE_TOKEN` as phone/browser access to your bridge.
- Treat `AEV_WEB_TOKEN` as upstream terminal access.
- Keep both tokens out of committed files.
- LAN binding means other devices on the network can attempt to connect.
- Use a strong bridge token when binding to `0.0.0.0`.
- Prefer trusted local networks; this is not an internet-exposed gateway.
## Development
```bash
cargo fmt --check
cargo test
cargo clippy --all-targets -- -D warnings
cargo publish --dry-run
```
## Release Notes
See `CHANGELOG.md`.