orca-cli-sdk
A typed Python SDK for the Orca CLI, with both sync and asyncio clients.
- Covers every command. All 287 commands in Orca CLI 1.4.237 are wrapped, generated from the CLI's own schema (
orca agent-context --json). - Mirrors the CLI.
orca worktree list --limit 5becomesclient.worktree.list(limit=5). - Uses the JSON envelope. Commands run with
--json, the SDK parses the{ok, result, error}envelope, and you getresultback. - Typed exceptions. Covers a missing binary, CLI errors (with
code/message/data), timeouts and bad JSON. - No runtime dependencies. Needs Python 3.10+.
uv add orca-cli-sdk # or: pip install orca-cli-sdk
# import name: orca_sdk
Quick start
from orca_sdk import Orca
orca = Orca()
status = orca.status()
print(status["runtime"]["state"]) # "ready"
for project in orca.project.list()["projects"]:
print(project["id"], project["displayName"])
repos = orca.repo.list()
worktrees = orca.worktree.list(repo="name:orca", limit=10)
Async
import asyncio
from orca_sdk import AsyncOrca
async def main() -> None:
async with AsyncOrca() as orca:
status, projects = await asyncio.gather(orca.status(), orca.project.list())
print(status["graph"]["state"], len(projects["projects"]))
asyncio.run(main())
AsyncOrca has the same methods and signatures as Orca, but each command must be awaited. It runs the CLI with asyncio.create_subprocess_exec. If a command times out or is cancelled, the SDK kills the CLI process.
Finding the orca binary
The binary is located the first time it is needed, checking in this order:
Orca(binary="/path/to/orca")- the
ORCA_BINenvironment variable orcaonPATH/home/box/Applications/bin/orca
If none of these is an executable file, the SDK raises OrcaBinaryNotFoundError. orca_sdk.find_binary() runs the same lookup.
Mapping CLI commands to methods
| CLI | Python |
|---|---|
orca status |
orca.status() |
orca worktree create --name t --agent codex --prompt "hi" |
orca.worktree.create(name="t", agent="codex", prompt="hi") |
orca worktree rm --worktree active --force |
orca.worktree.rm(worktree="active", force=True) |
orca terminal wait --terminal t1 --for exit --timeout-ms 60000 |
orca.terminal.wait(terminal="t1", for_="exit", timeout_ms=60000) |
orca reference add <url> <url> --worktree active |
orca.reference.add(["https://…", "https://…"], worktree="active") |
orca agent hooks status |
orca.agent.hooks.status() |
orca linear team list |
orca.linear.team.list() |
orca terminal-daemon status |
orca.terminal_daemon.status() |
orca serve service status |
orca.serve.service.status() (orca.serve(...) runs serve itself) |
Naming rules:
- Hyphens become underscores (
setup-clone→setup_clone). - Python keywords get a trailing
_(--for→for_,orca is→orca.is_). - Positional arguments are positional parameters.
- Flags are keyword-only parameters.
- Flags the usage string marks as required are required keywords.
How values become arguments:
- Boolean flags take
True. - Repeatable flags (
--reference,--label, …) take a list. None/Falseleaves the flag out.
Every method's docstring holds the CLI usage, notes and examples, so help(orca.worktree.create) shows what orca worktree create --help would.
The CLI's groups are all available, including:
project,repo,worktree,agent,terminalautomations,host,environment,skills,reference,accountorchestration,artifacts,file,tab,linear,jira,computer,emulator,storage,serve
Top-level commands are methods on the client: status, search, open, agent_context, snapshot, goto, click, and the rest.
Options: timeouts, env vars, remote runtimes
orca = Orca(
timeout=120, # seconds per command (default 60, None = no limit)
env={"NO_COLOR": "1"}, # extra env vars for the subprocess
inherit_env=True, # start from os.environ (default)
cwd="/path/to/worktree", # Orca infers the current worktree from cwd
)
# Route every command to a saved remote Orca server (adds --environment <name>)
remote = Orca(environment="build-box")
# ...or to one reached by a pairing code (passed as $ORCA_PAIRING_CODE so it
# does not appear in the process list)
paired = Orca(pairing_code="orca://pair?...")
# Derive a client with different options; the original is unchanged
slow = orca.with_options(timeout=600)
slow.terminal.wait(terminal="term_123", for_="exit", timeout_ms=600_000)
local = remote.with_options(environment=None)
Some commands only run on the local host and reject routing: account list, host list and environment list. The environment … management commands also take --environment as a selector (which server to act on), not as routing. Calling any of these on a client that has environment or pairing_code set raises OrcaUsageError before running anything. Use with_options(environment=None, pairing_code=None) to call them.
orca.environment.show(environment="build-box") # selector, not routing
Errors
from orca_sdk import (
OrcaError, # base class
OrcaBinaryNotFoundError, # no orca executable
OrcaCommandError, # the CLI reported ok=false or exited non-zero
OrcaTimeoutError, # killed after the timeout
OrcaJSONDecodeError, # --json output was not valid JSON
OrcaUsageError, # e.g. routing a host-local command
)
try:
orca.repo.show(repo="name:missing")
except OrcaCommandError as err:
print(err.code) # "repo_not_found"
print(err.message)
print(err.data) # error.data from the envelope, if any
print(err.next_steps) # the CLI's suggested next steps
print(err.returncode, err.argv, err.stderr)
If the CLI fails without printing a JSON envelope, you still get an OrcaCommandError, with code == "process_error" and the message taken from stderr.
Raw access
run_command runs any argument list. It returns the full OrcaResponse: ok, result, error, id, meta, stdout, stderr, returncode and argv.
resp = orca.run_command(["worktree", "ps", "--limit", "3"])
print(resp.meta["runtimeId"], resp.result)
resp = orca.run_command(["repo", "show", "--repo", "x"], check=False) # don't raise
if not resp.ok:
print(resp.error["code"])
orca.run_command(["claude-teams", "--help"], json=False) # plain-text commands
To feed stdin, pass stdin= to run_command or to the generated methods that read stdin (for example orca.speech.openai_key.set(stdin=key) or --text-stdin commands).
The bundled schema is available at runtime:
from orca_sdk.schema import load_schema, get_command, command_names
get_command("worktree create")["notes"]
Development
uv sync
uv run pytest # unit tests (subprocess is mocked)
ORCA_INTEGRATION=1 uv run pytest # also run read-only tests against the real orca
uv build
The integration tests only run read-only commands: status, project list, repo list, worktree list, host list, environment list, skills list, agent-context and a repo show that is expected to fail.
Regenerating the wrappers
src/orca_sdk/_generated.py is generated, so don't edit it by hand. To regenerate it after an Orca upgrade:
orca agent-context --json > src/orca_sdk/data/agent-context.json
# optional, improves flag typing: a dump of `orca <cmd> --help` for every command,
# each section headed by a line `== orca <cmd> --help`
python scripts/generate.py --help-dump /path/to/orca-cli-help.txt -v
uv run pytest
The schema lists each command's flag names but not whether a flag takes a value. The generator works that out from the usage string, then from the --help text, which it caches in data/flag-types.json. If neither settles it, the generator uses how the same flag is written in other commands. -v lists the flags typed that way. tests/test_generated.py checks that the generated file is up to date and that every command builds its expected argv.
License
MIT. See LICENSE.
Metadata
Release files for orca-cli-sdk 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| orca_cli_sdk-0.1.0.tar.gz | 151.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| orca_cli_sdk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 297.0 kB
Release files / orca_cli_sdk-0.1.0.tar.gz
| Download URL | orca_cli_sdk-0.1.0.tar.gz |
|---|---|
| Size | 151.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6849329b29a078da558d03147b829173503ff8206fb91d6a7a15d25cfbf837ff
|
|
BLAKE2b-256 checksum How to use checksums |
ddac3ce1fc2800a7d2cf3a3d1c24760a6a24ca0f4defdbde71c957ed8cc0d779
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / orca_cli_sdk-0.1.0-py3-none-any.whl
| Download URL | orca_cli_sdk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 145.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a00c042a1c3400d1f7faf87fe544b296f6ed4cbe75510379363a0b0abbd3650d
|
|
BLAKE2b-256 checksum How to use checksums |
e3218b68b69a3e9647bc24cda9dfcf5601ce83fc03600a4bfd7e4306b012f328
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for orca-cli-sdk 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.