cordis-cli 0.0.6

Command line runner (daemon/worker) for the cordis-rs plugin framework
Documentation
# cordis-cli

Command-line runner for the [cordis-rs](https://crates.io/crates/cordis-rs)
plugin framework: `cordis run <config.yml>`.

Builds on [cordis-loader](https://crates.io/crates/cordis-loader) to give a
config-driven cordis application a process model:

```console
$ cordis run cordis.yml
cordis: worker ready (2 entries, config: cordis.yml)
```

- **daemon / worker**`cordis run` supervises a worker subprocess that
  boots the loader. The worker exits with code `51` to request a hot
  restart and `52` to quit; only `51` respawns.
- **signals**`SIGINT` / `SIGTERM` dispose the root context gracefully
  and exit `52`, so Ctrl+C stops the whole application cleanly.
- **dotenv**`.env` and `.env.local` are loaded from the working
  directory at startup (existing environment variables always win), and
  `${{ env.NAME }}` templates in the config expand from there.
- **hot reload** — the entry file is watched (debounced); external edits
  reconcile fibers through the loader's diff machinery.

Plugins stop or restart the process through the `worker` service:

```rust,ignore
// inside a plugin's apply, with `ctx` the plugin context:
let handle = ctx.require::<cordis_cli::worker::WorkerHandle>("worker")?;
handle.restart(); // full worker reload (exit 51)
```

## Scope

The stock binary registers only the built-in `group` plugin; entries with
other names are recorded in the loader's `last_error()` and skipped.
Embedding applications register their own plugins via
[`cordis_loader::PluginRegistry`](https://docs.rs/cordis-loader) or fork
this runner; dynamic library loading (`dynamic` feature) is future work.