@octoryn/cli
v2.0.6
Published
Octoryn LLM official command-line interface
Maintainers
Readme
Octoryn LLM CLI
Official command-line interface for Octoryn LLM (Octopus Core Pty Ltd, ACN 696 931 236).
Note: the
octoryn devicescommand was renamed tooctoryn nodes. Thedevicesalias is kept for one release cycle (with a deprecation warning) and will be removed in a future release.
Install
npm (recommended, requires Node 20+):
npm install -g @octoryn/cliHomebrew (macOS / Linux):
brew install octopusos/tap/octorynSingle-file installer (no Node required):
curl -fsSL https://octopusos.dev/install.sh | shQuickstart
octoryn login # OIDC PKCE browser flow
octoryn whoami # show active identity + profile
octoryn chat -p "hello" # one-shot prompt
octoryn chat # interactive REPL (streamed)
octoryn agent run "draft weekly summary" # single-agent sync run
octoryn agent spawn "triage inbox" # async job for orchestration
octoryn agent wait <job_id> # wait on spawned job
octoryn agent spawn --mode worker "implement feature X"
octoryn agent spawn --mode subagent "research competitor pricing"
octoryn agent jobs approve <job_id> --step-id <step> --decision approve
octoryn agent jobs strategy <job_id> --permission-mode ask
octoryn agent fanout --mode subagent --item "task A" --item "task B" --wait
octoryn agent fanout --from-file ./tasks.jsonl --concurrency 8 --wait
octoryn agent jobs events <job_id> --follow
octoryn agent run "extract data" --output-format stream-json --json-schema ./schema.json
octoryn agent run "analyze screenshot" --image ./shot.png --session review-1
octoryn agent run "extract fields" --output-format stream-json --trace-file ./trace.jsonl
octoryn agent subagents add --name reviewer --system "Code review specialist"
octoryn agent subagents export --file ./subagents.json
octoryn agent subagents import --file ./subagents.json --dry-run
octoryn agent subagents run reviewer "review this diff"
octoryn agent sessions create review-1 --mode subagent --model gpt-4o-mini
octoryn agent sessions continue review-1 "follow-up question"
octoryn agent sessions fork review-1 --name review-1b
octoryn agent sessions history review-1 --append "First turn"
octoryn agent sessions update review-1 --name review-main
octoryn agent open ./apps/cli/src/cli.ts:42 --ide code
octoryn agent serve --host 127.0.0.1 --port 7788 --api-key devkey
# remote endpoints include:
# GET /health, GET /jobs, GET /jobs/:id, GET /stream/jobs/:id
# GET /sessions, DELETE /sessions/:id, POST /sessions/create, POST /sessions/update, POST /sessions/history/append, POST /sessions/history/clear, POST /sessions/fork, POST /sessions/continue
# /stream/jobs/:id supports ?events=status,step,result
# POST /open, POST /tools/query (supports cursor/next_cursor/rank)
# GET /mcp/servers, POST /mcp/servers, DELETE /mcp/servers/:server_id, GET /mcp/tools
# GET /subagents, POST /subagents/add, DELETE /subagents/:name, POST /subagents/run
octoryn agent mcp servers list
octoryn agent mcp tools
octoryn agent sessions list
octoryn agent sessions resume <session_id_or_job_id>
octoryn audit list # browse signed audit chain
octoryn edge models list # list manifest models (single source of truth)
octoryn edge models install litert-community/Qwen2.5-0.5B-Instruct --auto-load
octoryn edge models list --installed
octoryn edge chat --pii-redact-input "请脱敏:王敏 13800138000 [email protected]"
octoryn edge pii-redact "Call me at +1 202-555-0123, card 4111 1111 1111 1111"
octoryn chat --engine edge-local -p "Summarize this local note"Local smoke test (mock gateway + CLI e2e):
npm run test:e2e:agentConfiguration
Default endpoints point at the public production gateway:
| Setting | Default | Env override |
| ------------- | ----------------------------- | ------------------------ |
| gateway_url | https://api.octopusos.dev | OCTORYN_GATEWAY_URL |
| identity_url| https://id.octopusos.dev | OCTORYN_IDENTITY_URL |
| client_id | octoryn-cli | OCTORYN_CLIENT_ID |
| tenant_slug | (none) | OCTORYN_TENANT |
| edge_mode | cloud | OCTORYN_EDGE_MODE |
| edge_local_url | http://127.0.0.1:18080/v1 | OCTORYN_EDGE_LOCAL_URL |
For local development against a self-hosted stack:
octoryn config use dev # creates a 'dev' profile pointing at localhostConfig lives under env-paths('octoryn') (chmod 0600). Use
octoryn config list / get / set to inspect or override per profile.
Tool Sandbox
When the agent runs bash (and only bash — file IO and search tools
run in-process), the command is wrapped in an OS-level sandbox. The
default level is workspace-write; pass --sandbox strict to disable
network and writes outside the project root, or --no-sandbox to opt
out entirely.
| Platform | Backend | Status |
| -------- | ------------------ | --------------------------------------------------- |
| macOS | sandbox-exec | Shipped. SBPL profile, deny-default. |
| Linux | bwrap (bubblewrap) | Shipped. User-namespace + mount isolation. |
| Linux | Landlock LSM | Shipped + enforced. Rust helper auto-installed at npm install; real-kernel E2E covers ABI 1–4. |
| Windows | Job Objects | Shipped. |
Linux Landlock
Landlock is detected at startup when the kernel advertises support
(Linux 5.13+ for ABI 1; ABI 4 for network controls requires 6.7+).
Detection populates a typed probe (SandboxAvailability.landlock)
including the kernel release and best-effort ABI level, so callers can
log a precise reason when sandboxing degrades.
Enforcement requires three syscalls (landlock_create_ruleset,
landlock_add_rule, landlock_restrict_self) which Node does not
expose. We bridge this with a tiny Rust helper binary
(apps/cli/landlock-helper/) invoked as a subprocess. The helper:
- receives the JSON ruleset via the
OCTORYN_LANDLOCK_RULESETenv var (set by the CLI; scrubbed before exec), - calls the three syscalls via the upstream
landlockcrate, execvp()s the target child (bash -c …) so the sandboxed process replaces the helper PID — the CLI sees only the child.
The helper ships as a prebuilt static-musl binary uploaded to the
octopusos/octoryn-cli-bin GitHub Releases. The CLI's postinstall
hook (scripts/install-landlock-helper.cjs) downloads the matching
(linux × x86_64|aarch64) binary, verifies its SHA-256 sidecar (with
3-attempt exponential-backoff retry on transient HTTP failures), and
installs it at ~/.octoryn-cli/bin/landlock-helper. On Linux
x86_64/aarch64 the install is strict: download or SHA mismatch
fails the npm install rather than silently degrading. Set
OCTORYN_SKIP_LANDLOCK_HELPER=1 to bypass (the CLI then falls back to
bwrap).
Releases are auto-published from the build-landlock-helper GitHub
Actions workflow on tag pushes matching landlock-helper-v* (e.g.
landlock-helper-v0.1.0); the workflow uploads the binary, the
.sha256 sidecar, a .tar.gz archive, and a combined SHA256SUMS
file.
Kernel + ABI matrix
| Kernel ABI | Min kernel | Filesystem controls | Network controls |
| ---------- | ---------- | ------------------- | ---------------- |
| 1 | 5.13 | yes | no (use bwrap --unshare-net if needed) |
| 2 | 5.19 | + refer | no |
| 3 | 6.2 | + truncate | no |
| 4 | 6.7 | full | bind_tcp + connect_tcp |
The helper handles the highest known ABI it can negotiate with the running kernel; older kernels still get filesystem isolation.
Architecture matrix
| OS | Arch | Helper triple | Shipped |
| ----- | ------- | ----------------------------------- | ------- |
| linux | x86_64 | x86_64-unknown-linux-musl | yes |
| linux | aarch64 | aarch64-unknown-linux-musl | yes |
| linux | other | — | falls back to bwrap |
| macOS / Windows | — | — | helper not installed; native sandbox used |
Fallback behavior
The CLI degrades gracefully when the helper is missing or the kernel rejects the ruleset:
- Helper present + kernel supports Landlock → Landlock is enforced.
- Helper missing OR helper download failed → fall through to bwrap if available.
- Neither path → return a typed
SandboxUnavailableand require the user to opt in via--no-sandbox. We never silently skip.
Override / debug:
OCTORYN_LANDLOCK_HELPER=/path/to/binary— point at a custom helper (CI / self-built).OCTORYN_SKIP_LANDLOCK_HELPER=1— don't fetch on postinstall.OCTORYN_LANDLOCK_HELPER_VERSION=v0.1.0— pin a specific release.
Credential storage
API tokens (the OIDC access/refresh token bundle) are stored in your operating-system secret store, not in plaintext on disk:
| OS | Backend |
| -------- | --------------------------------------------------- |
| macOS | Keychain (service: octoryn-cli) |
| Windows | Credential Manager (target: octoryn-cli) |
| Linux | libsecret / GNOME Keyring / KWallet via Secret Service |
If the OS keychain is unavailable (typically headless Linux without
libsecret installed), the CLI falls back to an AES-256-GCM-encrypted
file at ${data_dir}/credentials.fallback.json and prints a single
octoryn.cli.credential.fallback warning to stderr. Install
libsecret-1-0 (Debian/Ubuntu) or libsecret (Fedora/Arch) to use the
real keychain.
Run octoryn auth status to see which backend is active. If you're
upgrading from a CLI version that wrote tokens in plaintext, run
octoryn auth migrate to move them into the OS keychain.
See docs/CLI-SECURITY.md for a deeper walk-through.
Local Edge Runtime
The CLI can talk to a local edge runtime that exposes OpenAI-compatible chat
plus model management endpoints, and can install models from the shared edge
manifest (config/edge/demo-model-manifest.v1.json):
POST /v1/chat/completionsGET /v1/edge/modelsPOST /v1/edge/models/load
This is aligned with the iOS EdgeNode local API.
Defaults:
- Base URL:
http://127.0.0.1:18080/v1 - Override via:
OCTORYN_EDGE_LOCAL_URLor--base-url - Optional bearer auth:
OCTORYN_EDGE_BEARER_TOKEN - Manifest override:
OCTORYN_EDGE_MODEL_MANIFEST_PATHorOCTORYN_EDGE_MODEL_MANIFEST_URL - Download token env:
OCTORYN_EDGE_MODEL_DOWNLOAD_TOKEN
Model install behavior:
edge models listreads model metadata from manifest (not hardcoded).edge models install <model_id>resolvesartifact_urlordownload_base_url + s3_key.- Adds
Authorization: Bearer <token>(or manifest-defined auth header). - Uses
aria2cresumable/concurrent download when available, then falls back to fetch+resume. - Verifies
sha256 + sizeafter download before marking local install available. - Prints model runtime (
litert-lm/litert) for downstream inference selection.
