Discovery
Plugins are executable binaries stored in~/.onecli/plugins/ with the naming convention oc-{name}. When you run oc google calendar list-events, oc looks for a binary at ~/.onecli/plugins/oc-google.
The plugin directory can be overridden with ONECLI_PLUGIN_DIR.
Manifest
Every plugin must respond to themanifest subcommand with a JSON object describing its capabilities:
Manifest fields
| Field | Type | Description |
|---|---|---|
name | string | Plugin name (matches binary name without oc- prefix) |
version | string | Semantic version |
description | string | Short description of what the plugin provides |
auth.required | boolean | Whether credentials are needed to run commands |
auth.local_flow | string | Auth flow type (e.g., "oauth"). Optional. |
auth.scopes | string[] | OAuth scopes or permission descriptions. Optional. |
commands | array | Available commands with descriptions and arguments |
commands[].name | string | Command name (can include subcommands separated by spaces) |
commands[].description | string | What the command does |
commands[].args | array | Available arguments |
commands[].args[].name | string | Argument name |
commands[].args[].required | boolean | Whether the argument is required |
commands[].args[].description | string | What the argument does |
Auth interface
Plugins that require authentication must respond to theauth subcommand. The auth flow uses newline-delimited JSON (NDJSON) on stdout:
status is "ok" and credentials.access_token is non-empty.
Auth response fields
| Field | Type | Description |
|---|---|---|
status | string | "pending", "ok", "authenticated", or "expired" |
credentials.access_token | string | The primary authentication token |
credentials.refresh_token | string | Optional refresh token |
credentials.token_type | string | Token type (usually "Bearer") |
credentials.expires_at | string | ISO 8601 expiration timestamp |
url | string | URL the user should visit (for device/OAuth flows) |
code | string | Code to display to the user (for device flows) |
message | string | Human-readable status message |
Command execution
When oc runs a plugin command, it:- Resolves credentials from the vault or local storage
- Injects credentials as environment variables into the plugin’s process
- Executes the plugin binary as a subprocess with the remaining arguments
- Passes stdin/stdout/stderr directly between the caller and the plugin
Environment variable injection
Credentials are passed as environment variables with the naming conventionOC_{PLUGINNAME}_{FIELD}:
| Variable | Source |
|---|---|
OC_GOOGLE_ACCESS_TOKEN | credentials.access_token |
OC_GOOGLE_REFRESH_TOKEN | credentials.refresh_token |
OC_GOOGLE_TOKEN_TYPE | credentials.token_type |
OC_GOOGLE_EXPIRES_AT | credentials.expires_at |
Execution model
Meta-commands
Two subcommands are special and run without credentials:manifestreturns the plugin’s manifest JSONauthruns the plugin’s authentication flow
Archive format
Plugin releases follow the goreleaser naming convention:oc-google_1.0.1_darwin_arm64.tar.gz
Each release must include a checksums.txt file with SHA256 hashes: