diff --git a/README.md b/README.md index 47d477d..e7d0df1 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,58 @@ The `.meta` file (`file_glob.meta`): Everything is sandboxed by default via Landlock. Tools that need to escape request elevation explicitly (`"elevated": true`). +### Privileged tools: `sudo` + +Tools that need root privileges declare `"sudo": true` in their `.meta`. The +dispatch chain becomes a two-gate sequence: elevation approval (escape sandbox) +→ credential prompt → `sudo -S` execution. The tool itself has no knowledge of +sudo — the privilege wrapping is entirely in the dispatch layer. + +```json +{ + "description": "Read system logs (dmesg).", + "sudo": true, + "cmd": "system_logs_dmesg", + "args": {"type":"object","properties":{"lines":{"type":"string"}}}, + "readOnly": true +} +``` + +Credentials are prompted via `kdialog`/`zenity` on desktop, or forwarded over +SSH for remote execution. See [doc/WRITING_TOOLS.md](doc/WRITING_TOOLS.md) for +details. + +### Host-conditional variants + +A single `.meta` file can describe a tool that works differently on different +hosts. Variants are gated by match conditions (`binary`, `file`, `os`, `arch`, +`env`, `nenv`). The first matching variant determines the tool's schema, +documentation, and executable. If no variant matches, the tool is hidden from +the registry — it doesn't exist on this host. + +```json +{ + "description": "Read system logs.", + "variants": [ + { + "match": {"binary": "journalctl"}, + "cmd": "system_logs_journald", + "args": {"type":"object","properties":{"unit":{"type":"string"},"since":{"type":"string"}}} + }, + { + "match": {"file": "/var/log/syslog"}, + "cmd": "system_logs_syslog", + "args": {"type":"object","properties":{"lines":{"type":"string"}}} + } + ] +} +``` + +On a systemd host the model sees unit filtering and time ranges. On Alpine it +sees tail + grep. On a host with neither, the tool doesn't appear. One `.meta` +deploys everywhere. See [doc/WRITING_TOOLS.md](doc/WRITING_TOOLS.md) for the +full variant specification. + ## What you can do | Capability | How | diff --git a/doc/USAGE.md b/doc/USAGE.md index a00212b..c33490b 100644 --- a/doc/USAGE.md +++ b/doc/USAGE.md @@ -486,6 +486,9 @@ Each tool has a `.meta` JSON sidecar file alongside the executable: | `args` | JSON Schema for tool input parameters | | `tier` | Result cacheability: `cold`, `warm`, or `hot` (default: hot) | | `readOnly` | Safe for parallel execution with other read tools | +| `cmd` | Executable path or name; overrides co-located binary (see WRITING_TOOLS.md) | +| `sudo` | Requires root privileges; implies elevation | +| `variants` | Array of conditional definitions for heterogeneous hosts (see WRITING_TOOLS.md) | ### Runtime access @@ -503,6 +506,54 @@ Agents query `/tools` when they need detailed usage for a specific tool. Drop an executable and its `.meta` file in `$OLLIE_TOOLS_PATH`. The next session created will pick it up automatically. No restart required. +### Host-conditional variants + +Tools can declare multiple **variants** gated by match conditions. The first +variant where all conditions pass determines the tool's schema, documentation, +and executable. If no variant matches, the tool is hidden from the registry. + +```json +{ + "description": "Read system logs.", + "variants": [ + { + "match": {"binary": "journalctl"}, + "cmd": "system_logs_journald", + "args": {"type":"object","properties":{"unit":{"type":"string"},"since":{"type":"string"}}} + }, + { + "match": {"file": "/var/log/syslog"}, + "cmd": "system_logs_syslog", + "args": {"type":"object","properties":{"lines":{"type":"string"}}} + } + ] +} +``` + +Supported match keys: `binary`, `file`, `os`, `arch`, `env`, `nenv`. All +conditions in a match must be true (AND). Values can be a string or array +(OR). See [WRITING_TOOLS.md](WRITING_TOOLS.md) for the full specification. + +### Privileged tools: `sudo` + +Tools that need root privileges declare `"sudo": true` in their `.meta`. The +dispatch chain becomes a two-gate sequence: elevation approval (escape sandbox) +→ credential prompt → `sudo -S` execution. The tool itself has no knowledge of +sudo — the privilege wrapping is entirely in the dispatch layer. + +```json +{ + "description": "Read system logs (dmesg).", + "sudo": true, + "cmd": "system_logs_dmesg", + "args": {"type":"object","properties":{"lines":{"type":"string"}}}, + "readOnly": true +} +``` + +Credentials are prompted via `kdialog`/`zenity` on desktop, or forwarded over +SSH for remote execution. See [WRITING_TOOLS.md](WRITING_TOOLS.md) for details. + ## Alternative front-ends The 9P filesystem is the lowest level interface to ollie. All interfaces are wrappers around filesystem operations. Front-ends: