flare-plugin-host 0.1.1

Flare 能力插件的宿主接入库:声明、注册、注销
Documentation
# echo-plugin

A complete, runnable Flare capability plugin in about 130 lines.

It does nothing useful on purpose. Its value is that it is **complete**:
declaration, registration, context restoration, JSON encoding, unknown-operation
handling and graceful withdraw are all here, and all short enough to read in one
sitting.

Every dependency comes from crates.io — no path dependencies — so it builds
anywhere, not just inside the Flare multi-repo workspace.

## Run it

```bash
cargo run
```

```text
echo-plugin 监听 127.0.0.1:7901,对外通告 127.0.0.1:7901
已向 http://127.0.0.1:50110 声明 2 个 operation
```

The platform does not have to be running: if it cannot be reached the plugin
says so and keeps serving. A plugin that exits because the platform is late
starting is a plugin that cannot survive a rolling restart.

| Variable | Default | Meaning |
|---|---|---|
| `ECHO_PLUGIN_LISTEN` | `127.0.0.1:7901` | Where the gRPC server binds |
| `ECHO_PLUGIN_ADVERTISE` | same as listen | The address **the platform** calls back on |
| `CAPABILITY_ENDPOINT` | `http://127.0.0.1:50110` | The platform's capability service |

`ADVERTISE` is separate from `LISTEN` because in a container they are rarely the
same string, and announcing an address the platform cannot reach fails as a
health-check problem rather than a configuration one.

## Operations

| Operation | Payload | Result |
|---|---|---|
| `example.echo.say` | `{"text": "hi"}` | echoes the text plus the caller's tenant/user |
| `example.echo.upper` | `{"text": "hi"}` | echoes it uppercased |

`example.echo.say` returns the tenant and user ids on purpose: it proves the
plugin restored the calling context out of request metadata. The platform calls
you out of process, so no framework middleware does that for you.

## The test that matters

`cargo test` checks the declaration list against the dispatch arms. Those two
drifting apart is the most common plugin bug, and it fails in two directions
with completely different symptoms:

- declared but not implemented → the request arrives and you answer
  `UNKNOWN_OPERATION`, which looks like the plugin is broken
- implemented but not declared → the platform rejects it and your process never
  sees it, which looks like a permissions problem

Copy this test into your own plugin.