use crate::boundary::help::{HelpRow, Surface, render};
#[cfg(test)]
mod tests;
pub(super) const COMMANDS: &[HelpRow] = &[
HelpRow {
verb: crate::wire::provision::verb::SUBCMD,
usage: "yog wire-certs",
summary: "mint this box's wire certificates: a local CA and its server/client leaves",
detail: "Write a private CA and the server, client and window leaves into the wire \
material directory, plus the one `address` file naming what the engine binds \
and a seat dials. The engine's own boot already does this for a box that has \
none, aimed at loopback, so this is the act for everything else: a server \
another machine dials by name (`WIRE_HOST=engine.example.com WIRE_PORT=7737`), \
a different directory (`WIRE_DIR`), or a rotation (`FORCE=1`). It refuses to \
overwrite otherwise, because a rotation distrusts every certificate already \
issued and every seat holding one stops connecting. `WIRE_LEAF=<common-name>` \
asks for the other act instead: issue ONE extra client leaf under that name, \
over the CA already here — no CA, no address, no other leaf. That is the leaf \
a visiting box participates as; carry it, its key and `ca.pem` to that box by \
hand and place them in its `wire/workspaces/<leaf>/` as `client.pem`, \
`client.key` and `ca.pem`, beside an `address` naming this engine. The common \
name INSIDE the certificate is the identity, not the basename, so the rename \
costs nothing. It shells to `openssl`: provisioning is the operator's \
out-of-channel act and yog links no certificate library.",
surface: Surface::Machine,
},
HelpRow {
verb: crate::fixture::verb::SUBCMD,
usage: "yog fixture [state]",
summary: "lay a named, deterministic world state for a client harness to dial",
detail: "Write one of a fixed roster of world states into a scratch data root and \
print, as one JSON object, everything a harness needs to dial an engine \
booted on it: the root, the address, the CA and the client leaf. Bare, it \
lists the roster. Booting is the caller's — `XDG_DATA_HOME=<root> yog` — \
because the caller is the one that has to kill it, and tearing down is `rm \
-rf <root>`. `FIXTURE_ROOT` names the root (the default is a stable \
path under this box's cache root), and `WIRE_HOST`/`WIRE_PORT` state the address \
the material is minted for, exactly as `wire-certs` reads them; with no \
port stated a free one is taken from the kernel, because a `127.0.0.1:0` in \
the material is a request only the listener ever learns the answer to. It \
REFUSES a root that overlaps this box's own yog data root in either \
direction: a lay wipes its root before it writes. The `hold` list it \
answers with names the fds a harness keeps open for the run to make a \
streaming conversation read as a live model call — a live call is derived \
from an open descriptor, so no tree on disk can be one by itself.",
surface: Surface::Machine,
},
HelpRow {
verb: crate::world::hatch::ENV_SUBCMD,
usage: "yog env [--ws WORKSPACE]",
summary: "print the world's environment (`eval \"$(yog env)\"`)",
detail: "Print one shell `export` line per world override, quoted so `eval` reproduces \
each value byte-for-byte. `eval \"$(yog env)\"` drops the calling shell into \
yog's nested world, where a bare `bl`/`litany`/`bz` is the world's own shim \
into yog's embedded substrate. `--ws WORKSPACE` also stands that workspace's \
wall, which is what a `bz` needs: providers, sign-ins and the model cache \
belong to a workspace, and without one bz refuses rather than reaching the \
machine's own. Prints only; it starts nothing.",
surface: Surface::Machine,
},
HelpRow {
verb: crate::world::hatch::EXEC_SUBCMD,
usage: "yog exec [--cwd DIR] [--ws WORKSPACE] <cmd…>",
summary: "run one command inside the composed world",
detail: "Run exactly one command with the world's environment standing, and exit with \
that command's own code. `--ws WORKSPACE` also stands that workspace's wall, \
which is how a headless seat signs in: `yog exec --ws WORKSPACE bz --login \
--provider NAME --browser` writes the credential into that workspace and \
nowhere else. The leading flags are yog's; every argument from the command \
word on belongs to the command. Bad usage exits 2, a command that could not \
be spawned exits 127.",
surface: Surface::Machine,
},
HelpRow {
verb: crate::control::SUBCMD,
usage: "yog tool-control",
summary: "",
detail: "The capability control an embedded litany consults before each granted tool \
invocation: it speaks a line protocol over stdin/stdout and is spawned with \
no arguments beyond this word. Nothing types it by hand.",
surface: Surface::Machine,
},
HelpRow {
verb: "gesture",
usage: "yog gesture <gesture>",
summary: "cross the control boundary: a JSON envelope or a /slash line",
detail: "Deposit one gesture into the running world's inbox and print the reply. The \
payload is a JSON envelope or a `/slash` line; `--ws / --agent / --project / \
--as` state the context a terminal has no selection for. `yog gesture --help` \
lists every gesture and `yog gesture --help <command>` is one gesture's page.",
surface: Surface::Machine,
},
HelpRow {
verb: "litany",
usage: "yog litany <argv…>",
summary: "the embedded litany, in yog's own process",
detail: "Run litany's own verb surface in this process, against the nested world. The \
argv after the word is litany's, so `yog litany --help` is litany's own usage.",
surface: Surface::Machine,
},
HelpRow {
verb: "bl",
usage: "yog bl <argv…>",
summary: "the embedded balls, on the composed world's store",
detail: "Run balls' own verb surface in this process, against the world's store and \
landing. The argv after the word is balls', so `yog bl --help` is balls' own \
usage.",
surface: Surface::Machine,
},
HelpRow {
verb: "bz",
usage: "yog bz <argv…>",
summary: "the embedded brazen (sign in with `yog exec --ws WORKSPACE bz --login …`)",
detail: "Run brazen's own surface in this process. Providers, sign-ins and the model \
cache belong to a workspace, so every route but a discovery probe needs a \
workspace wall standing — a bare `yog bz --login` outside one is refused \
rather than signing in somewhere shared. Name the workspace with a hatch: \
`yog exec --ws WORKSPACE bz --login --provider NAME --browser`, or stand the \
wall for a whole shell with `eval \"$(yog env --ws WORKSPACE)\"`. The argv \
after the word is brazen's, so `yog bz --help` is brazen's own usage.",
surface: Surface::Machine,
},
];
pub(super) fn answer(argv: &[String]) -> Option<String> {
let word = argv.get(1)?.as_str();
if matches!(word, "--help" | "-h" | "help") {
let about = argv.get(2).map(String::as_str);
return Some(about.and_then(page).unwrap_or_else(super::usage));
}
if super::Namespace::from_arg(word).is_some_and(super::Namespace::owns_argv) {
return None;
}
matches!(argv.get(2).map(String::as_str), Some("--help" | "-h"))
.then(|| page(word))
.flatten()
}
fn page(verb: &str) -> Option<String> {
COMMANDS
.iter()
.find(|row| row.verb == verb)
.map(|row| render(&[*row]))
}
pub(crate) fn is_discovery(args: &[String]) -> bool {
matches!(
args,
[only] if matches!(only.as_str(), "--help" | "-h" | "--version" | "-V" | "--skill")
)
}