# Hello sample bridge — Rust flavor

One of two parallel reference bridges for the Adom Desktop bridge SDK. The Rust flavor is a single static binary — no Python install on the user's machine, no `pip install`, no runtime dependencies. **Fork this when you want a self-contained native bridge** (one `.exe` to ship, faster cold start, type-safe error handling, ideal for CPU-bound work). Kept in lock-step with [`skills/BRIDGE_SDK.md`](../../../skills/BRIDGE_SDK.md) — every current author contract is demonstrated in `src/main.rs`.

The Python sibling lives at [`scripts/sample-bridges/hello-python/`](../hello-python/) — same surface, different verb prefix (`hellopy_` vs `hellors_`). Both use `port: 0` (v1.8.31+ dynamic OS-assigned ports), so they can be installed simultaneously with no port-collision worry.

## What it does

Three verbs:

- `hellors_ping` → returns `{"success": true, "output": "Hello from the Rust sample bridge v1.3.0!", "language": "rust", ...}`
- `hellors_echo` with `{"message": "..."}` → echoes the message back as `"echo (rust): <msg>"`
- `hellors_describe` → the self-doc catalog AD renders in its Verbs tab (one entry per verb, with hint/related/pitfalls)

It also demonstrates the current author contracts you should copy: loopback bind via `ADOM_BIND_HOST`, the self-reported status-chip LED, rich `_hint`s, caller-provenance logging (it prints which AI thread + container drove each call), and a throttled `_reportIssues` line inviting bug reports.

## How it gets installed end-to-end

Relay calls (from a cloud container / galliaApril) each need `--ai-thread "<your thread name>"` — AD refuses a relayed command with no caller identity (`errorCode: caller_identity_required`). Shown on the first line; add it to every relayed call. A LOCAL `adom-desktop-cli.exe` on the same PC as AD does not need it.

```bash
# (from galliaApril, or any machine with adom-desktop CLI on PATH)
adom-desktop --ai-thread "my-thread" bridge_install '{"manifestUrl":"https://wiki.adom.inc/api/v1/pages/adom-desktop-hello-rust-bridge/files/adom-bridge-hello-rust-manifest.json"}'

# Confirm it's loaded
adom-desktop --ai-thread "my-thread" bridge_list
# → "hello-rust" appears alongside the bundled bridges + any other installed third-party bridges

# Call a verb
adom-desktop --ai-thread "my-thread" hellors_ping
adom-desktop --ai-thread "my-thread" hellors_echo '{"message":"world"}'

# Uninstall when done
adom-desktop --ai-thread "my-thread" bridge_uninstall '{"name":"hello-rust"}'
```

## Anatomy

| File | Purpose |
|---|---|
| `bridge.json` | Required manifest. Declares name, version, spawn config (`kind: "exe"`), verb prefixes. |
| `BRIDGE_VERSION` | Convenience version line (kept in sync with `bridge.json`'s `version`). |
| `Cargo.toml` | Rust crate manifest. Two deps: `tiny_http` (~5K LOC HTTP/1.1) + `serde`/`serde_json`. |
| `src/main.rs` | The bridge runtime. ~180 lines including comments. |
| `hello-rust.exe` | Pre-built Windows x64 binary, included in the wiki-shipped zip. Linux/macOS users rebuild. |

## Why pick Rust over Python (see hello-python)

- **Single static binary.** Users don't need Python installed. One `.exe` in the zip, no `pip install`, no virtualenv setup. Cold start in <10ms vs Python's ~100ms.
- **CPU-bound work scales.** Heavy parsing, image processing, encoding/decoding — Rust is dramatically faster than Python for the same algorithm.
- **Static typing + strict error handling.** Catches a class of bugs at compile time (missing fields, nullable returns) that Python only hits at runtime when a user invokes the broken verb.
- **Tight memory.** A bridge listening on a port costs ~3 MB resident in Rust vs ~30 MB for the Python interpreter + stdlib.

## Why pick Python over Rust (see hello-python)

- **Vendor has Python bindings.** KiCad's `pcbnew`, Autodesk Fusion 360's add-in API, MATLAB Engine, NI-VISA, etc. all have first-class Python.
- **No build step.** Edit `server.py`, restart the bridge, done. Zero compile latency during development.
- **Shorter for I/O-bound work.** Spawning subprocesses, parsing files, talking to HTTP services — Python's stdlib gets you there in fewer lines.

## Building from source

```bash
# Windows (Adom Desktop's primary host platform)
cd scripts/sample-bridges/hello-rust
cargo build --release
cp target/release/hello-rust.exe .          # the zip ships the binary next to bridge.json

# Linux / macOS (rebuild for your platform before zipping)
cargo build --release
cp target/release/hello-rust .              # note: no .exe suffix
#   then edit bridge.json: "entrypoint": "hello-rust" (drop the .exe)
#   and "platforms.linux.supported": true (or macos)
```

The release profile is tuned for binary size (`opt-level = "z"`, LTO, `panic = "abort"`, strip) — expect ~1-2 MB on Windows x64. tiny_http + serde are the only deps.

## Shipping a new version

```bash
# 1. Bump BRIDGE_VERSION + bridge.json's "version" + Cargo.toml's "version" (all three together)
# 2. Rebuild the binary
cd scripts/sample-bridges/hello-rust && cargo build --release && cp target/release/hello-rust.exe .

# 3. Package + upload to wiki
bash scripts/release-bridge.sh hello-rust

# 4. Tell installed clients to refresh
adom-desktop refresh_bridges
```

## What's NOT in the zip (intentionally)

- No `target/` directory — only the final binary at the bridge root. Keeps the zip small (~1-2 MB vs ~80 MB for full target/).
- No source at all in the runtime zip — the zip ships only `hello-rust.exe` + `bridge.json`. Source (`src/`, `Cargo.toml`, `Cargo.lock`) lives in this repo for fork-and-rebuild; ship `Cargo.lock` in the SOURCE repo for reproducible rebuilds, not in the runtime zip.

## When to scale up from this template

Two verbs and a static dispatch match aren't a real bridge. For a real bridge that drives a complex application (Altium, MATLAB), you'd add:

- A `handlers/` module pattern (one `.rs` per verb category, see the Python `plugins/kicad/handlers/` for the layout).
- A vendor SDK crate as a dependency (e.g. `pyo3` if you're wrapping a Python lib, `windows` crate for COM automation).
- Persistent state (a `RwLock<State>` shared across requests) for connection pools, document caches, etc.
- Caller-provenance forwarding if your bridge calls AD back: forward the `X-Adom-Caller-*` headers it received + add `X-Adom-Caller-Delegate: hello-rust` (BRIDGE_SDK.md "Caller provenance"). This sample only reads + logs them.
- A skills pkg (USER docs) published separately from the runtime zip — the two-artifact layout in the SDK. This sample ships runtime-only.

For inspiration, look at the bundled Puppeteer bridge (`plugins/puppeteer/`) — it's a Node bridge but the same architectural patterns translate directly to Rust.
