{"name":{"finding":"OpenHands CLI (main-repository lineage), researched 2026-10-27. Current main ships Agent Canvas; no current one-prompt-and-exit CLI established. Canvas, historical monorepo TUI and SDK features are distinguished below.","quote":"<h1 align=\"center\" style=\"border-bottom: none\">Agent Canvas</h1>","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/README.md","third_party":false},"repo":{"finding":"https://github.com/OpenHands/OpenHands; current package @openhands/agent-canvas exposes agent-canvas. Not the archived OpenHands/OpenHands-CLI repository.","quote":"\"agent-canvas\": \"bin/agent-canvas.mjs\"","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/package.json","third_party":false},"docs":{"finding":"https://docs.openhands.dev/; current documentation index emphasizes Agent Canvas/SDK. No standalone CLI guide was found in this index.","quote":"# OpenHands Docs","url":"https://docs.openhands.dev/llms.txt","third_party":false},"headless":{"finding":"not found","quote":"@openhands/agent-canvas - Run the Agent Canvas UI with agent-server","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/bin/agent-canvas.mjs","third_party":false,"details":[{"finding":"CURRENT MAIN: agent-canvas --backend-only starts services, not one prompt followed by exit. No prompt-file/stdin/workdir/auto-approval flags or per-task exit-code contract found. Help lists port, host, public/frontend/backend modes, version/info/help. Launcher exits 0 for help/version/info and 1 for startup errors; these are service-launcher codes.","quote":"--backend-only        Start only agent-server + automation behind ingress","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/bin/agent-canvas.mjs","third_party":false},{"finding":"HISTORICAL V1 TUI (1.0.7-cli): parser has --resume and serve (--mount-cwd/--gpu), not one-shot/headless/prompt-file/workdir flags. Chat loops on input after each run; /exit asks confirmation. Piping a prompt was not established as a supported one-shot contract.","quote":"user_input = session.prompt(","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/agent_chat.py","third_party":false}]},"confinement":{"finding":"Current local execution has host filesystem/shell/network access. Optional Docker, tool selection, hooks and approval policies provide distinct controls; none establishes a current one-shot CLI.","quote":"machine it runs on, execute shell commands, and reach the network.","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/docs/SELF_HOSTING.md","third_party":false,"details":[{"finding":"DOCKER: OH_CONVERSATION_RUNTIME=docker agent-canvas creates per-conversation containers, host UID/GID, cap-drop ALL, no-new-privileges, authenticated loopback API. Canvas/outer server stay trusted host processes. Bind-mounted /workspace and persistence/history survive removal; shared host workspace means shared writable files. No seatbelt/gVisor/bubblewrap boundary established.","quote":"Drops all Linux capabilities (`--cap-drop ALL`) and sets `no-new-privileges`.","url":"https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/docker-execution.md","third_party":false},{"finding":"TOOLS: named OpenHands profiles choose only selected tools; default profile uses global toolset. mcp_server_refs limits MCP servers; absent refs means all configured servers. This is capability selection, not a shell-command allowlist.","quote":"**Choose tools** — The agent gets only the tools you select. Removing a tool removes the ability, not just the instruction to avoid it.","url":"https://docs.openhands.dev/openhands/usage/agent-canvas/agent-profiles.md","third_party":false},{"finding":"COMMAND ALLOW/DENY: cookbook offers custom PreToolUse allowlist/denylist plugins. Allowlist matches command names, needs separate subcommand validation, is not full shell parsing; denylist lets unlisted patterns run. Not a built-in CLI allow/deny flag.","quote":"Each command name is matched exactly - no wildcards or partial matches.","url":"https://docs.openhands.dev/cookbook/command-whitelist.md","third_party":false},{"finding":"HOOKS: .openhands/hooks.json supports tool matchers. Synchronous PreToolUse exit 2 or JSON decision=deny blocks; 0 allows; other codes log error and proceed. Async hooks cannot block. Operator must install/configure policy.","quote":"* `2` - Block. The operation is denied.","url":"https://docs.openhands.dev/openhands/usage/customization/hooks.md","third_party":false},{"finding":"FILES: cookbook path-guard example covers navigation, writes/redirects and editor writes, but lacks full shell parsing/path canonicalization and fails open on parsing errors. It is not an OS sandbox.","quote":"**Fails open** - If hook can't parse input, it allows the operation (for safety)","url":"https://docs.openhands.dev/cookbook/workspace-isolation.md","third_party":false},{"finding":"APPROVAL MODES (SDK/server): AlwaysConfirm requires all actions approved; NeverConfirm runs without approval; ConfirmRisky depends on analyzer risk. These do not themselves confine filesystem/network. Unattended wrappers must resolve confirmations or choose a noninteractive policy.","quote":"**`NeverConfirm()`** - Execute all actions without approval","url":"https://docs.openhands.dev/sdk/guides/security.md","third_party":false},{"finding":"NETWORK: current Docker mode maps host.docker.internal to host gateway. No network-off/egress-allowlist switch found in launcher, Docker execution configuration or self-hosting guide. API loopback bindings/keys/inbound firewall rules must not be treated as egress denial.","quote":"Maps `host.docker.internal` to the host gateway.","url":"https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/docker-execution.md","third_party":false},{"finding":"HISTORICAL V1 TUI: setup uses local Workspace, persistence and AlwaysConfirm, not DockerWorkspace or another OS sandbox. Cwd alone is not a write boundary.","quote":"workspace=Workspace(working_dir=WORK_DIR),","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/setup.py","third_party":false}]},"token_reporting":{"finding":"Yes at conversation/SDK level; no automatic current coding-CLI final usage JSON established. Current Canvas consumes structured backend metrics; historical V1 exposes /status text.","quote":"stats.usage_to_metrics","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/utils/conversation-metrics.ts","third_party":false,"details":[{"finding":"CURRENT CANVAS: aggregates accumulated_cost across usage IDs and accumulated_token_usage.prompt_tokens, completion_tokens, cache_read_tokens, cache_write_tokens; carries context_window/per_turn_token. UI total=input+output. No separate reasoning_tokens in inspected aggregation/UI.","quote":"value={(usage.prompt_tokens + usage.completion_tokens).toLocaleString()}","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/components/features/conversation/metrics-modal/usage-section.tsx","third_party":false},{"finding":"SDK FORM: llm.metrics.model_dump() gives programmatic metrics; conversation.conversation_stats.get_combined_metrics() aggregates main/auxiliary LLM costs. An SDK/API wrapper can export these, rather than assuming a coding-CLI stdout schema.","quote":"get_combined_metrics()`**: Returns a single `Metrics` object that aggregates costs across all LLMs used in the conversation.","url":"https://docs.openhands.dev/sdk/guides/metrics.md","third_party":false},{"finding":"OFFICIAL API COOKBOOK, separate utility: oh-metrics <conversation_id> --json outputs accumulated_cost and accumulated_token_usage (prompt/completion/cache read/cache write/context window); reasoning_tokens documented when applicable. Can retrieve ConversationStateUpdateEvent.value.stats.usage_to_metrics.agent, V0 llm_metrics events or trajectories. Not proof coding CLI emits reasoning usage.","quote":"| `reasoning_tokens` | Tokens used for reasoning (if applicable) |","url":"https://docs.openhands.dev/cookbook/conversation-metrics.md","third_party":false},{"finding":"HISTORICAL V1 /status text: input/output/cache read/cache write/total and accumulated USD cost to six decimals, via conversation.conversation_stats.get_combined_metrics(). Interactive status, not documented automatic final JSON.","quote":"('   Total Cost (USD):', cost_str),","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/tui/status.py","third_party":false}]},"parallelism":{"finding":"Current Canvas supports concurrent conversations/parallel children; SDK supports synchronous task subagents and configurable concurrent calls. No current headless-CLI concurrency flag established.","quote":"This is useful for running several agents concurrently.","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/README.md","third_party":false,"details":[{"finding":"CURRENT MAIN CHILD CLIENT TOOL: independent child runs without blocking parent/sharing history or output. target local/cloud; local isolation worktree (default, new worktree/branch from default branch) or shared (same directory). Canvas client feature, not established in a clientless headless CLI.","quote":"Start a NEW, independent conversation to work on a well-scoped task in parallel with this one, without the user having to run any CLI command.","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/api/launch-child-conversation-client-tool.ts","third_party":false},{"finding":"SDK SUBAGENTS: parent includes Tool(name=TaskToolSet.name); register_agent(name, factory_func) defines specialized types, default general-purpose type exists; tasks can resume via task ID. Sequential/blocking by default.","quote":"TaskToolSet is designed for **sequential** blocking tasks.","url":"https://docs.openhands.dev/sdk/guides/task-tool-set.md","third_party":false},{"finding":"SDK PARALLEL: increase Agent.tool_concurrency_limit (e.g. 4/8) to execute independent calls, including multiple TaskToolSet subagents, concurrently within one model response. Subagents can set own limits. Experimental. Multiple Canvas sessions can instead use OH_CONVERSATION_RUNTIME=docker and distinct host workspaces.","quote":"By default, `tool_concurrency_limit` is set to `1` (sequential execution).","url":"https://docs.openhands.dev/sdk/guides/parallel-tool-execution.md","third_party":false}]},"providers":{"finding":"OpenHands uses LiteLLM providers/models. Support does not establish equal capability or independent testing of all models; current docs do not prove historical CLI compatibility.","quote":"OpenHands can connect to any LLM supported by LiteLLM. However, it requires a powerful model to work.","url":"https://docs.openhands.dev/openhands/usage/llms/llms.md","third_party":false,"details":[{"finding":"Official provider guides: AWS Bedrock, Azure, DigitalOcean, Google Gemini/Vertex, Groq, Moonshot AI, OpenAI, OpenHands, OpenRouter, LiteLLM Proxy and local LLMs. Not an exhaustive LiteLLM catalog.","quote":"For a full list of the providers and models available, please consult the","url":"https://docs.openhands.dev/openhands/usage/llms/llms.md","third_party":false},{"finding":"Settings name OpenHands, Anthropic, OpenAI and Mistral AI as verified providers. Provider/model/key or custom model/base URL configurable.","quote":"Mistral AI.","url":"https://docs.openhands.dev/openhands/usage/settings/llm-settings.md","third_party":false},{"finding":"LOCAL: LM Studio, Ollama, vLLM, SGLang and Atomic Chat via OpenAI-compatible endpoints; exact model ID/provider prefix, backend-reachable base URL and endpoint credentials required.","quote":"alternative backends like Ollama, Atomic Chat, SGLang, or vLLM","url":"https://docs.openhands.dev/openhands/usage/llms/local-llms.md","third_party":false},{"finding":"ACP external agents have their own providers/auth/tools; hosting Claude Code/Codex/Gemini CLI/Pi/OpenCode is not equivalent to native OpenHands provider support.","quote":"ACP Agent Profiles use the external agent's own model and authentication flow instead.","url":"https://docs.openhands.dev/openhands/usage/agent-canvas/agent-profiles.md","third_party":false}]},"subscription_login":{"finding":"Yes in current built-in OpenHands integration for OpenAI ChatGPT subscription; not established for historical monorepo CLI. External ACP subscriptions are separate.","quote":"{ label: \"ChatGPT subscription\", value: LLM_AUTH_TYPE_SUBSCRIPTION },","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/constants/llm-subscription.ts","third_party":false,"details":[{"finding":"CURRENT MAIN: auth_type api_key/subscription, subscription_vendor openai. Service calls OpenAI /device/start, /device/poll, /status, /models and /logout under /api/llm/subscription/openai. This is device-code authentication requiring initial account authorization, not automatic unattended signup.","quote":"static async startOpenAIDeviceLogin(): Promise<LLMSubscriptionDeviceChallenge>","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/api/llm-subscription-service.ts","third_party":false},{"finding":"SDK: ChatGPT Plus/Pro accesses Codex models without API credits using LLM.subscription_login(vendor=\"openai\", model=...). First OAuth login needs browser authorization; credentials cached/automatically refreshed. open_browser=False prints URL, does not authorize itself. Docs call OpenAI first subscription provider supported.","quote":"The SDK handles OAuth authentication, credential caching, and automatic token refresh.","url":"https://docs.openhands.dev/sdk/guides/llm-subscriptions.md","third_party":false},{"finding":"EXTERNAL ACP ONLY: backend can reuse Claude Code Pro/Max, Codex ChatGPT, Gemini Google, Pi or OpenCode stored login for those external agents. Native built-in OpenHands Claude/Gemini/GitHub Copilot subscription or no-key vendor-plan flow not found. OpenHands LLM provider uses its API key.","quote":"For an ACP agent, the selected backend launches the provider's CLI and must have access to its subscription login or API key.","url":"https://docs.openhands.dev/openhands/usage/agent-canvas/acp-agents.md","third_party":false}]},"license":{"finding":"MIT (SPDX MIT), current LICENSE.","quote":"The MIT License (MIT)","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/LICENSE","third_party":false},"latest_stable":{"finding":"Repository-wide newest non-draft/non-prerelease by published_at: v1.33.0, ISO date 2026-10-23; published_at=2026-10-23T13:46:20Z. Agent Canvas release, not Python CLI 1.33.0.","quote":"\"tag_name\":\"v1.33.0\"","url":"https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100","third_party":false,"details":[{"finding":"GitHub releases API publication timestamp.","quote":"\"published_at\":\"2026-10-23T13:46:20Z\"","url":"https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100","third_party":false},{"finding":"Registry @openhands/agent-canvas latest=1.33.0, bin agent-canvas, MIT, repo OpenHands/OpenHands.","quote":"\"version\":\"1.33.0\"","url":"https://registry.npmjs.org/@openhands/agent-canvas/latest","third_party":false},{"finding":"PyPI openhands latest=1.16.0, summary OpenHands CLI - Terminal User Interface for OpenHands AI Agent. Current source provenance was not established within requested repo; its behavior is not substituted.","quote":"\"version\":\"1.16.0\"","url":"https://pypi.org/pypi/openhands/json","third_party":false}]},"latest_prerelease":{"finding":"not found","quote":"[]","url":"https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100&page=3","third_party":false,"details":[{"finding":"Scanned all public releases: page 1=100 entries, page 2=55, page 3 empty. None prerelease=true; no tag/date available.","quote":"\"prerelease\":false","url":"https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100","third_party":false},{"finding":"Second API page likewise has no prerelease=true records.","quote":"\"prerelease\":false","url":"https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100&page=2","third_party":false}]},"last_commit":{"finding":"Default main: 311dc1be63758e51d61e43d6574d5c03c7a30688; author/committer 2026-10-27T00:29:09Z (ISO date 2026-10-27). Message: chore: bump @openhands/extensions to 0.36.0 and automation to 1.26.0 (#18993).","quote":"\"date\":\"2026-10-27T00:29:09Z\"","url":"https://api.github.com/repos/OpenHands/OpenHands/commits?sha=main&per_page=1","third_party":false},"fork_of":{"finding":"GitHub fork=false; no official evidence found of a fork of another coding agent. OpenDevin is its former name, not evidence of a fork.","quote":"\"fork\":false","url":"https://api.github.com/repos/OpenHands/OpenHands","third_party":false,"details":[{"finding":"Historical renamed project lineage.","quote":"Welcome to OpenHands (formerly OpenDevin), a platform for software development agents powered by AI.","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/README.md","third_party":false}]},"maintenance":{"finding":"Not archived (archived=false), current Canvas commits/releases; no unmaintained marker found in current README/docs index. Does not establish maintenance of the old in-repo CLI.","quote":"\"archived\":false","url":"https://api.github.com/repos/OpenHands/OpenHands","third_party":false,"details":[{"finding":"Current repository owns Canvas frontend/control center/backend selection/local orchestration; SDK/server/agent/tool execution belongs to software-agent-sdk.","quote":"Agent Canvas frontend, user-facing control center, backend selection, and local-stack orchestration.","url":"https://raw.githubusercontent.com/OpenHands/OpenHands/main/README.md","third_party":false},{"finding":"CLI directory path history last change: Cleanup CLI directory (#12669), 02825fb5bb0f12a9e1b7c685ef2995b70d574fc1, 2026-01-29T14:14:50Z.","quote":"Cleanup CLI directory (#12669)","url":"https://api.github.com/repos/OpenHands/OpenHands/commits?path=openhands-cli&per_page=1","third_party":false},{"finding":"Historical core/main.py path history last change: APP-1363 : Remove V0 io Package (#14094), 478c998f04d19bc522a35052fd93bfb62879cb3f, 2026-04-23T15:31:01Z.","quote":"APP-1363 : Remove V0 io Package (#14094)","url":"https://api.github.com/repos/OpenHands/OpenHands/commits?path=openhands/core/main.py&per_page=1","third_party":false}]},"gaps":[{"finding":"No current-main one-task CLI, prompt-file/stdin/workdir/approval flags or task exit-code contract established. Historical CLI snapshots are not current support.","checked":["https://raw.githubusercontent.com/OpenHands/OpenHands/main/bin/agent-canvas.mjs","https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/argparsers/main_parser.py","https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/agent_chat.py"]},{"finding":"No current launcher egress-off/allowlist or seatbelt/gVisor/bubblewrap found. No automatic CLI usage JSON/session-file schema; separate reasoning count absent from inspected Canvas aggregation and old /status.","checked":["https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/docker-execution.md","https://raw.githubusercontent.com/OpenHands/OpenHands/main/docs/SELF_HOSTING.md","https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/utils/conversation-metrics.ts","https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/components/features/conversation/metrics-modal/usage-section.tsx"]},{"finding":"No current headless-CLI subagent flag, historical CLI OAuth or native Claude/Gemini/Copilot/OpenHands-plan subscription flow established. Canvas/SDK/ACP alternatives are distinguished.","checked":["https://raw.githubusercontent.com/OpenHands/OpenHands/main/bin/agent-canvas.mjs","https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/constants/llm-subscription.ts","https://docs.openhands.dev/sdk/guides/llm-subscriptions.md","https://docs.openhands.dev/openhands/usage/agent-canvas/acp-agents.md","https://docs.openhands.dev/openhands/usage/agent-canvas/llm-profiles.md"]},{"finding":"No prerelease in 155 public API releases. Current PyPI CLI provenance not established as requested current-main source. Research only; did not run a model task.","checked":["https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100","https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100&page=2","https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100&page=3","https://pypi.org/pypi/openhands/json"]}],"sources":["https://raw.githubusercontent.com/OpenHands/OpenHands/main/README.md","https://raw.githubusercontent.com/OpenHands/OpenHands/main/package.json","https://docs.openhands.dev/llms.txt","https://raw.githubusercontent.com/OpenHands/OpenHands/main/bin/agent-canvas.mjs","https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/agent_chat.py","https://raw.githubusercontent.com/OpenHands/OpenHands/main/docs/SELF_HOSTING.md","https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/docker-execution.md","https://docs.openhands.dev/openhands/usage/agent-canvas/agent-profiles.md","https://docs.openhands.dev/cookbook/command-whitelist.md","https://docs.openhands.dev/openhands/usage/customization/hooks.md","https://docs.openhands.dev/cookbook/workspace-isolation.md","https://docs.openhands.dev/sdk/guides/security.md","https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/setup.py","https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/utils/conversation-metrics.ts","https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/components/features/conversation/metrics-modal/usage-section.tsx","https://docs.openhands.dev/sdk/guides/metrics.md","https://docs.openhands.dev/cookbook/conversation-metrics.md","https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/tui/status.py","https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/api/launch-child-conversation-client-tool.ts","https://docs.openhands.dev/sdk/guides/task-tool-set.md","https://docs.openhands.dev/sdk/guides/parallel-tool-execution.md","https://docs.openhands.dev/openhands/usage/llms/llms.md","https://docs.openhands.dev/openhands/usage/settings/llm-settings.md","https://docs.openhands.dev/openhands/usage/llms/local-llms.md","https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/constants/llm-subscription.ts","https://raw.githubusercontent.com/OpenHands/OpenHands/main/src/api/llm-subscription-service.ts","https://docs.openhands.dev/sdk/guides/llm-subscriptions.md","https://docs.openhands.dev/openhands/usage/agent-canvas/acp-agents.md","https://raw.githubusercontent.com/OpenHands/OpenHands/main/LICENSE","https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100","https://registry.npmjs.org/@openhands/agent-canvas/latest","https://pypi.org/pypi/openhands/json","https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100&page=3","https://api.github.com/repos/OpenHands/OpenHands/releases?per_page=100&page=2","https://api.github.com/repos/OpenHands/OpenHands/commits?sha=main&per_page=1","https://api.github.com/repos/OpenHands/OpenHands","https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/README.md","https://api.github.com/repos/OpenHands/OpenHands/commits?path=openhands-cli&per_page=1","https://api.github.com/repos/OpenHands/OpenHands/commits?path=openhands/core/main.py&per_page=1","https://raw.githubusercontent.com/OpenHands/OpenHands/1.0.7-cli/openhands-cli/openhands_cli/argparsers/main_parser.py","https://docs.openhands.dev/openhands/usage/agent-canvas/llm-profiles.md","https://docs.openhands.dev/cookbook/command-blacklist.md"]}
