aev-bridge 0.1.1

Aev bridge plugin for phone-friendly terminal access.
Documentation
# 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

| Setting | CLI | Environment | Default |
| --- | --- | --- | --- |
| 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`.