Skip to content

v2.2.0

Choose a tag to compare

@haofeif haofeif released this 04 Jun 11:25
4fada4e

v2.2.0 — 2026-06-04

Highlights

CAO 2.2 introduces persistent agent memory — agents can now store and recall knowledge across sessions through memory_store / memory_recall / memory_forget MCP tools, with global / project / session / agent scoping, BM25 fallback retrieval over a SQLite index, file-lock-safe concurrent writes, per-scope caps, and stable project identity via git remote. Memories auto-inject as <cao-memory> context at session start. Plus a new external-tool integration path that lets CAO orchestrate non-CAO CLI agents (OpenClaw, Hermes Agent, etc.) as first-class workers, handoff terminals that auto-delete after completion with snapshot-based restore, eager inbox delivery for providers that buffer input mid-turn, --env forwarding through cao launch to supervisors and children, codex / claude_code profile fields (codexProfile, permission_mode), an official devcontainer feature, and a stack of TUI-detection, security, and dependency fixes.

Added

  • CAO memory (Phase 1 + 2 + 2.5 hardening) — Three-phase build of a persistent agent memory system. Phase 1 lays down the storage foundation: memory_store / memory_recall / memory_forget MCP tools, scope-based partitioning under ~/.aws/cli-agent-orchestrator/memory/, and a CLI surface (cao memory list/show/delete/clear). Phase 2 adds SQLite metadata, BM25 fallback retrieval, and <cao-memory> context injection at session start via a context manager. Phase 2.5 hardens the system with per-scope caps (10 entries / 1000 chars), an ISO-8601 Z round-trip lock on index.md, real-multiprocess flock contention tests, a memory.enabled short-circuit on recall, and stable project identity via canonicalized git remote (with cwd-hash alias for repos without a remote). See docs/memory.md by @fanhongy in #245, #254, #262

  • External tool integration (OpenClaw, Hermes Agent) — A new external-tool-integration skill lets CAO orchestrate non-CAO CLI agents as first-class workers. Hermes Agent is shipped as a worked end-to-end example — see docs/external-tool-integration.md by @anilkmr-a2z and @haofeif in #241, #253

  • CAO operations MCP server (cao-mcp-server) — Exposes CAO's session/terminal/launch operations to LLM agents as MCP tools, so a supervisor can drive cao launch, cao session list, etc. via tool calls instead of shell invocations by @patricka3125 in #166

  • Auto-delete handoff terminals with snapshot-based restorehandoff workers now self-delete on completion. The supervisor still sees the worker's final output through a captured snapshot, so cross-provider handoff results survive cleanup by @anilkmr-a2z in #233

  • Shell command tracking, flow recycling, inbox delivery reliability — Tracks shell commands per terminal for diagnostics; recycles flow records to avoid unbounded growth; and tightens inbox delivery so messages don't get stuck in PENDING when the receiver was briefly busy by @anilkmr-a2z in #230

  • Eager inbox delivery for buffering providers — Providers like Gemini CLI that buffer pasted input during processing now receive inbox messages eagerly the moment they reach a deliverable state, instead of waiting for a polling tick by @anilkmr-a2z in #251

  • cao launch --env forwarding to supervisor and child agents — Operators can now forward env vars through cao launch --env; the values travel in the JSON request body (not the URL) so secrets don't land in cao-server access logs and propagate to every worker spawned in the session by @call-me-ram in #259

  • codexProfile field on AgentProfile (codex provider) — Optional codexProfile frontmatter key lets codex agent profiles select a named codex profile at launch by @kjanoudi in #250

  • permission_mode field on AgentProfile (claude_code provider) — Optional permission_mode frontmatter key for fine-grained Claude Code permission control beyond the universal allowedTools vocabulary by @kjanoudi in #244

  • Official devcontainer feature — A reusable devcontainer feature for CAO so contributors can spin up a fully-provisioned dev environment with one click by @ThePlenkov in #260

  • Web UI: filtering, sorting, grouping, and session deletion — Dashboard home gains client-side filter/sort/group, plus a session-delete action so stale sessions can be cleaned up from the browser by @gutosantos82 in #200

  • OpenCode provider label in Web UIopencode_cli now appears in the Web UI's provider pickers and /agents/providers response, with a friendly "OpenCode" source label by @patricka3125 in #217

  • Auto-derive CORS origins from cao-server --host/--port — CORS allowlist is now built from the bind address by default, so the Web UI works out of the box on remote hosts without manual CAO_CORS_ORIGINS configuration by @call-me-ram in #261

Fixed

  • Codex: detect v0.136+ TUI footer (model · path without N% left) — codex 0.136 dropped the N% left segment from the status bar, so TUI_FOOTER_PATTERN never matched and get_status() couldn't tell the suggestion-hint line apart from a real user message. Handoff and assign workers were pinning at IDLE forever. Pattern extended to anchor on the path component shared across v0.111 and v0.136 footers by @haofeif

  • Codex: skip • Called <tool>(...) MCP tool-call markers during last-message extraction — the extractor anchored on the first after the user prompt, which can be a tool-call marker; the tool output that follows (e.g. the cao-worker-protocols skill body containing [CAO Handoff]) leaked into the extracted response. The extractor now iterates matches and skips MCP tool-call markers; ASSISTANT_PREFIX_PATTERN was also tightened from \s*• to [^\S\n]*• so the match anchors on the bullet line itself, not a preceding blank line by @haofeif

  • Kiro CLI: paste-into-boot-screen race that dropped the first message after launch — kiro shows a M of N mcp servers initialized line before the idle prompt becomes interactive, so a paste arriving in this window was silently absorbed by the boot screen. TUI_INITIALIZING_PATTERN extended to match this line, and Check 3 (shell-baseline = IDLE) gated on self._initialized so get_status() no longer returns IDLE while kiro is still exec'ing by @haofeif in #268

  • CI: stop TestPyPI squats breaking the release smoke test — the publish workflow's --extra-index-url to TestPyPI let a squatted FASTAPI 1.0 package outrank real fastapi and break the build. The smoke test now installs our package from TestPyPI with --no-deps and resolves dependencies from PyPI alone, with a fail-fast chain by @haofeif in #270

  • Always honor profile.provider at launch (yolo + allowed-tools paths)resolve_provider previously lived inside one branch of the permission-resolution conditional in launch.py, so --yolo and --allowed-tools paths silently dropped the profile's provider: frontmatter field. Cross-provider workflows where each profile pins a specific CLI now work in every launch path by @call-me-ram in #257

  • Resolve profile.provider in create_session()POST /sessions passed the caller-supplied provider straight through, so the Web UI and any HTTP client ignored profile.provider. The fix preserves explicit --provider over the profile (CLI flag wins) by @gutosantos82 in #198

  • MCP worker provider resolution + ops MCP profile provider — Two related fixes ensuring spawned MCP workers and ops MCP sessions honor the agent profile's declared provider instead of falling back to the supervisor's CLI by @patricka3125 in #224, #229

  • MCP: reject send_message when receiver_id equals sender — Prevents an agent from accidentally messaging itself, which produced infinite forwarding loops on some providers by @call-me-ram in #263

  • Wait for IDLE before tmux attach (non-headless launch) — Non-headless cao launch attached the moment the API returned, racing the provider's TUI init and silently dropping early keystrokes. Mirrors the headless path's wait_until_terminal_status(IDLE/COMPLETED) with a warn-and-attach fallback on timeout by @haofeif in #221 (resolves #220)

  • Kiro CLI: false-IDLE during Initializing... — The new TUI renders the idle-prompt placeholder before init completes; CAO matched the placeholder and dropped the first user message. TUI_INITIALIZING_PATTERN now unconditionally returns PROCESSING during the init phase by @haofeif in #215 (resolves #211)

  • Kiro CLI: SIGWINCH input death from attach-time tmux resize — kiro-cli 2.1.x dropped all input after the 80×24 → real-terminal resize that fired on cao launch attach. Panes are now created at 220×50 so the attach-time resize is a no-op or small shrink that kiro repaints correctly by @haofeif in #218 (resolves #216)

  • Kiro CLI: handoff hang for Q Developer Pro (no Credits marker) — Q Developer Pro doesn't emit the ▸ Credits: marker that CAO used as a completion sentinel in TUI mode. Detection now falls back to the idle-prompt-after-input rule with a separator-based response extractor by @joedarc in #238

  • Gemini CLI: isolate GEMINI.md per terminal in a dedicated workspace — Multiple Gemini terminals previously shared one GEMINI.md file via the cwd, racing on writes. Each terminal now gets its own workspace directory by @haofeif in #227

  • OpenCode: poller drains stuck PENDING messages — Adds a periodic drain to OpenCode's inbox delivery path so messages that hit a transient PENDING state don't sit forever by @patricka3125 in #210

  • tmux: filter environment to prevent 'command too long' errors — Pane creation copied the full parent environment, occasionally exceeding tmux's command-line limit on hosts with verbose env. Filtered to a known-safe allowlist by @gutosantos82 in #246

  • API: default TERM to xterm-256color for tmux PTY attach — Some hosts have TERM=dumb or unset, breaking color rendering and TUI providers on WebSocket attach. Force xterm-256color at the boundary by @call-me-ram in #256 (resolves #150)

  • API: configurable network allowlists via env varsCAO_ALLOWED_HOSTS and related allowlists are now env-tunable, so deployments behind reverse proxies can opt in to additional Host headers without code changes by @call-me-ram in #255

Documentation

  • Reorganized README + control-plane overview — Split the long README into topic docs and added a control-plane diagram so newcomers can see how cao-server, MCP, and the providers fit together by @haofeif in #225

  • Web UI build instructions + 404 troubleshooting — Updated the Web UI dev-loop docs and added a section on the most common 404 (built assets missing from the wheel) by @wahidzzz in #252

  • Install via PyPI in README — Documents the pip install cli-agent-orchestrator path now that the wheel is published by @fanhongy in #214

Security

  • CodeQL #66 — tmux name validation — Hardens session/window name validation against command injection on every entry point that builds a tmux command line, including a defence-in-depth re-validation at WebSocket attach by @haofeif in #258

  • Agent-name path traversal in profile lookupload_agent_profile() resolved user-supplied agent names against profile directories without a path-containment check, allowing ../-style escapes that CodeQL flagged with 8 path-injection alerts by @haofeif in #228

  • Agent-profile install — SSRF + path injectioncao agent install <url> is now hardened against SSRF (URL allowlist, redirect cap) and against profile-name path injection through the install flow by @haofeif in #226

  • Bump idna 3.10 → 3.15 by @dependabot in #247

  • Bump authlib 1.6.11 → 1.6.12 by @dependabot in #236

  • Bump urllib3 2.6.3 → 2.7.0 by @dependabot in #234

  • Bump python-multipart 0.0.26 → 0.0.27 by @dependabot in #232

  • Bump vitest 3.2.4 → 4.1.0 in /web (devDependency) by @dependabot in #267

New Contributors

Upgrade

uv tool install git+https://github.com/awslabs/cli-agent-orchestrator.git@v2.2.0 --upgrade

Or via PyPI:

pip install --upgrade cli-agent-orchestrator==2.2.0

No breaking changes to existing CLI invocations or agent profiles. Memory is opt-in per agent profile (memory.enabled) and inert when disabled. Existing handoff workflows continue to work — handoff workers now auto-delete on completion, and the supervisor sees the worker's final output through a snapshot.

Full Changelog: v2.1.1...v2.2.0