All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Launch prompt clarity +
--auto-approve— Redesign thecao launchconfirmation prompt to showRoleinstead ofBlocked, clearly distinguish[Y]/[--auto-approve]/[--yolo], and add--auto-approveflag to skip the prompt without removing restrictions (for automated flows, scripts, and agent-to-agent launches)
- Kiro CLI new TUI support — Add fallback detection patterns for the new Kiro CLI TUI prompt format (
ask a question, or describe a task), ensuring CAO works even if--legacy-uiis removed in a future version - Agent profile exception handling (#137) — Fix
load_agent_profile()wrappingFileNotFoundErrorasRuntimeError, which causedassign()to fail for JSON-only agent profiles (AIM-installed kiro-cli agents). Callers now receiveFileNotFoundErrordirectly and handle it gracefully - Missing providers in Web UI (#157) — Add
gemini_cli,kimi_cli, andcopilot_clito the/agents/providersendpoint and frontend fallback list so all 7 providers appear in the Web UI dropdown
- Gemini CLI provider — Full integration with Google's Gemini CLI, including status detection, message extraction, and E2E tests (#102)
- Kimi CLI provider — Support for Moonshot's Kimi CLI with agent profiles and MCP server integration (#113)
- Copilot CLI provider — Native GitHub Copilot CLI provider (#82)
- Web UI dashboard — React-based web interface for managing sessions, spawning agents, viewing live terminal status, configuring agent directories, and interacting with agents from the browser (#108)
- Provider override in agent profiles — Agent profiles can now specify a
providerfield to override the default provider, enabling cross-provider workflows (#101) - Auto-inject sender terminal ID — New
CAO_ENABLE_SENDER_ID_INJECTIONenv var automatically appends sender terminal ID and callback instructions toassignandsend_messagemessages, removing the need for manual prompt engineering (#98) - Cross-provider example profiles and updated README with
gemini_clidocumentation (#109)
- Claude Code bypass permissions prompt — Auto-set
skipDangerousModePermissionPromptin~/.claude/settings.jsonand handle the bypass prompt via subprocess on startup, preventing initialization hangs (#120) - Claude Code Processing spinner — Fix regex to catch newer spinner format (#92)
- Codex TUI footer detection — Update detection for Codex v0.111.0 (#99)
- Q CLI unit tests — Fix failing tests due to working directory validation changes (#94)
- Terminal init status — Accept both IDLE and COMPLETED during terminal initialization for providers with initial prompts (#111)
- 400 Bad Request on non-home directories — Fix launching agents in directories outside
~/(e.g.,/Volumes/workplaceon macOS) (#110) - Gemini CLI extraction retry — Add extraction retry for TUI-based providers where premature COMPLETED status can occur (#117)
- Path traversal in agent profile loading — Validate agent names to reject
/,\, and..before path construction (CodeQL py/path-injection) (#129) - Pre-existing test failure — Fix
test_skips_provider_dir_same_as_localfailing on macOS due to/homesymlink resolution (#129)
- Add DNS rebinding protection via Host header validation (#124)
- Add CodeQL SafeAccessCheck guard for path injection in API (#121)
- Pin trivy-action to SHA instead of mutable
masterref in CI (#126) - Bump vite 5→6.4.1 and vitest 2→3.2.4 to fix esbuild vulnerability GHSA-67mh-4wv8-2f99 (#129)
- Bump requests 2.32.5→2.33.0 for CVE-2026-25645 (#130)
- Bump authlib 1.6.7→1.6.9 (#122)
- Bump pyjwt 2.11.0→2.12.0 (#118)
- Bump black 25.9.0→26.3.1 (#114)
- Fix
_handoff_impl()only accepting IDLE as ready state: providers with initial prompts reach COMPLETED after processing the system prompt; updated to accept both IDLE and COMPLETED via multi-statuswait_until_terminal_status() - Fix
wait_until_terminal_status()only accepting a single status: now acceptsUnion[TerminalStatus, set]for polling multiple acceptable statuses - Fix handoff worker IDLE wait timeout too short (30s) for slow-initializing providers: some providers can exceed 30s during shell warm-up, CLI startup, and MCP server registration; increased to 120s to act as a fallback
- Fix inbox message delivery failing for TUI-based providers: inbox service passed
tail_lines=5toget_status()but TUI providers need 50+ lines to find the idle prompt; messages stayed PENDING forever because the supervisor was never detected as IDLE - Fix inbox watchdog log tail check (
_has_idle_pattern) using only 5 lines, which missed the idle prompt for full-screen TUI providers where the prompt sits mid-screen with 30+ padding lines below; increased to 100 lines so the watchdog reliably triggers delivery when the terminal goes IDLE - Fix shell command injection risk in Q CLI and Kiro CLI providers: replace f-string command interpolation with
shlex.join()for safe shell escaping ofagent_profilevalues - Fix Claude Code provider not forwarding
CAO_TERMINAL_IDto MCP server subprocesses: injectCAO_TERMINAL_IDinto MCP serverenvconfig, matching other providers - Fix Claude Code provider failing to launch due to tmux
send-keyscorrupting single quotes in long commands; resolved by main branch's paste-buffer approach (load-buffer+paste-buffer -p) - Add missing
wait_for_shellcall to Claude Code providerinitialize()to match other providers - Update Claude Code
IDLE_PROMPT_PATTERNto match both>and❯prompt styles - Add
_handle_trust_prompt()to Claude Code provider to auto-accept the workspace trust dialog when opened in a new/untrusted directory; exclude trust prompt fromWAITING_USER_ANSWERdetection - Fix Codex provider failing to launch in tmux: add warm-up
echo readycommand before starting codex to prevent immediate exit in fresh sessions - Fix Codex idle prompt detection for
--no-alt-screenmode: replace\Z-anchored regex with bottom-N-lines approach (IDLE_PROMPT_TAIL_LINES = 5) since inline mode keeps scrollback history - Fix Codex trust prompt
›falsely matching idle prompt pattern by checking trust prompt before idle prompt inget_status() - Fix Codex status detection not recognizing real interactive output format: update
ASSISTANT_PREFIX_PATTERNto match•bullet responses andUSER_PREFIX_PATTERNto match›user input prompts, enablingget_status()to returnCOMPLETEDfor real Codex output (previously always returnedIDLE, causing handoff/assign to time out) - Fix
USER_PREFIX_PATTERNcrossing newline boundaries: use[^\S\n](horizontal whitespace) instead of\sto prevent› \n ?from matching as user input - Add
IDLE_PROMPT_STRICT_PATTERNfor extraction: matches only empty prompt lines (›without text) to distinguish idle prompts from user input lines - Rewrite
extract_last_message_from_script()to use user-message-based extraction as primary approach (works for both label and bullet formats) with assistant-marker fallback - Fix Codex MCP
tool_timeout_secnot taking effect: change value from600(TOML integer) to600.0(TOML float) because Codex deserializes viaOption<f64>and silently rejects integers, falling back to the 60s default - Fix handoff worker agents not returning results: prepend
[CAO Handoff]context to the message in_handoff_impl()so the worker agent knows this is a blocking handoff and should output results directly instead of attempting to callsend_messageback to the supervisor (which fails because the worker doesn't have the supervisor's terminal ID) - Fix Codex TUI footer causing false IDLE during handoff:
› Summarize recent commitsin the TUI status bar matchedUSER_PREFIX_PATTERNas a user message, preventing COMPLETED detection; now detects TUI footer (? for shortcuts/context left) and excludes bottom lines from user-message matching - Fix Codex TUI progress spinner causing false COMPLETED:
• Working (0s • esc to interrupt)matchedASSISTANT_PREFIX_PATTERNwhile TUI›hint matched idle prompt; addedTUI_PROGRESS_PATTERNcheck to return PROCESSING when spinner is active - Fix Codex output extraction returning TUI chrome: apply same TUI footer detection to
extract_last_message_from_script()and usecutoff_posas extraction boundary when no strict idle prompt found - Fix Codex extraction of multi-line user messages: find first
•assistant marker after user message instead of skipping one line, correctly handling wrapped[CAO Handoff]prefix text - Fix Claude Code worker agents blocking on workspace trust prompt during handoff/assign: add
--dangerously-skip-permissionsflag to bypass trust dialog since CAO already confirms workspace trust duringcao launch - Fix Claude Code
PROCESSING_PATTERNnot matching newer Claude Code 2.x spinner format: broaden pattern to match both(esc to interrupt)and(Ns · ↓ tokens · thinking)formats - Fix all providers'
send_input()usingtmux send_keys(literal=True)which sends characters individually, allowing TUI hotkeys to intercept user messages; replace withsend_keys_via_paste()usingtmux set-buffer+paste-buffer -p(bracketed paste mode) to bypass per-character hotkey handling
- E2E assign callback round-trip test (
test_assign_with_callback) for all providers: verifies full assign flow where worker completes task, result is sent to supervisor's inbox, inbox message delivered (status=DELIVERED), and supervisor processes the callback - E2E send_message test now verifies inbox message status = DELIVERED (not just stored), proving the inbox delivery pipeline works end-to-end for each provider
- E2E supervisor orchestration test now verifies no inbox messages stuck as PENDING after supervisor completes, catching inbox delivery pipeline failures
- Workspace trust confirmation prompt in
launch.pybefore starting providers: asks "Do you trust all the actions in this folder?" since providers are granted full permissions (read, write, execute) in the working directory; supports--yoloflag to skip - Unit tests for
TmuxClient.send_keysvalidating paste-buffer delivery (test/clients/test_tmux_send_keys.py) - Claude Code unit tests for
wait_for_shelllifecycle, shell timeout,❯prompt detection, and ANSI-coded output - Trust prompt handling tests (6 tests) and workspace confirmation tests (4 tests)
- Codex provider agent profile support: inject system prompt via
-c developer_instructionsconfig override, mirroring Claude Code's--append-system-promptbehavior - Codex provider MCP server support: inject MCP servers from agent profiles via
-c mcp_servers.<name>.<field>=<value>config overrides (per-session, no global config changes), enabling tools likehandoffandsend_messagefor multi-agent orchestration - Codex MCP server
CAO_TERMINAL_IDenvironment forwarding: automatically addsenv_vars=["CAO_TERMINAL_ID"]to all MCP server configs so handoff can create new agent windows in the same tmux session - Codex
_build_codex_command()method withshlex.join()for safe shell escaping and proper quote/backslash/newline handling - Codex launch flags:
--no-alt-screen(inline mode for reliable tmux capture) and--disable shell_snapshot(prevent SIGTTIN in tmux) - Codex
_handle_trust_prompt()to auto-accept workspace trust dialog during initialization - Codex unit tests:
TestCodexBuildCommand(10 tests) for command building, agent profile injection, MCP server config, escaping, and error handling - Codex bullet-format status detection tests:
TestCodexBulletFormatStatusDetection(7 tests) for COMPLETED, PROCESSING, IDLE, code blocks, error detection, multi-turn, and TUI status bar using real•bullet response format - Codex bullet-format extraction tests:
TestCodexBulletFormatExtraction(5 tests) for single-line, multi-line, code block, multi-turn, and no-trailing-prompt extraction from•bullet format - Codex TUI spinner status detection tests:
test_get_status_processing_tui_spinner,test_get_status_processing_tui_thinking_spinner,test_get_status_processing_dynamic_spinner_text(3 tests) verifying PROCESSING is returned when TUI progress spinner is active - Handoff message context tests:
TestHandoffMessageContext(6 tests) intest/mcp_server/test_handoff.pyverifying[CAO Handoff]prefix is prepended only for Codex provider, includes supervisor terminal ID, and preserves the original message - Multi-agent communication protocol section added to
developer.mdandreviewer.mdagent profiles explaining handoff vs assign behavior - End-to-end test suite (
test/e2e/) with 15 tests covering handoff, assign, and send_message flows across all 3 providers (codex, claude_code, kiro_cli); uses realdata_analystandreport_generatorprofiles fromexamples/assign/; gated behind@pytest.mark.e2emarker, excluded from defaultpytestruns - Provider documentation:
docs/claude-code.mdanddocs/kiro-cli.mdcovering status detection, message extraction, configuration, implementation notes, E2E testing, and troubleshooting - CI workflow
test-codex-provider.ymlfor Codex provider-specific unit tests (path-triggered) - CI workflow
test-claude-code-provider.ymlfor Claude Code provider-specific unit tests (path-triggered) BaseProvider.mark_input_received()hook called byterminal_service.send_input()after delivering external input; allows providers to adjust status detection based on whether external input has been received since initializationTmuxClient.send_keys_via_paste()method for sending text via bracketed paste mode (tmux set-buffer+paste-buffer -p), bypassing TUI hotkey interceptionTmuxClient.send_special_key()method for sending tmux key sequences (e.g.,C-d,C-c) non-literally, distinct fromsend_keys()which sends text literally- Supervisor orchestration E2E tests (
test/e2e/test_supervisor_orchestration.py): tests across providers that verify the full supervisor→worker delegation flow via MCP tools (handoff and assign+handoff), usinganalysis_supervisorprofile fromexamples/assign/ terminal_service.send_special_key()wrapper function for the new tmux client method- Exit terminal endpoint key sequence routing:
POST /terminals/{terminal_id}/exitnow detectsC-/M-prefixed exit commands and sends them as tmux key sequences instead of literal text - New CLI commands:
cao info(show session info) andcao mcp-server(start MCP server) - New example profiles:
data_analystandreport_generatorinexamples/assign/ - Kiro CLI provider: comprehensive docstrings and
shlex.join()shell safety fix - Q CLI provider:
shlex.join()shell safety fix - Session service: comprehensive docstrings
- Handle CLI prompts with trailing text (#61)
- Dynamic working directory inheritance for spawned agents (#47)
- Release workflow version parsing (#60)
- Escape newlines in Claude Code multiline system prompts (#59)
- Bump python-multipart from 0.0.20 to 0.0.22 (#58)
- Bump werkzeug from 3.1.1 to 3.1.5 (#55)
- Bump starlette from 0.48.0 to 0.49.1 (#53)
- Bump urllib3 from 2.5.0 to 2.6.3 (#52)
- Bump authlib from 1.6.4 to 1.6.6 (#51)
- Remove unused constants and enum values (#45)
-
async delegate (#3)
-
add badge to deepwiki for weekly auto-refresh (#13)
-
add Codex CLI provider (#39)
- rename 'delegate' to 'assign' throughout codebase (#10)
-
Handle percentage in agent prompt pattern (#4)
-
resolve code formatting issues in upstream main (#40)
-
Initial commit
-
Initial Launch (#1)
-
Inbox Service (#2)
-
tmux install script (#5)
-
update README: orchestration modes (#6)
-
Update README.md (#7)
-
Update issue templates (#8)
-
Document update with Mermaid process diagram (#9)
-
Adding examples for assign (async parallel) (#11)
-
update idle prompt pattern for Q CLI to use consistent color codes (#15)
-
Add comprehensive test suite for Q CLI provider (#16)
-
Add code formatting and type checking with Black, isort, and mypy (#20)
-
Make Q CLI Prompt Pattern Matching ANSI color-agnostic (#18)
-
Add explicit permissions to workflow
-
Kiro CLI provider (#25)
-
Add GET endpoint for inbox messages with status filtering (#30)
-
Adding git to the install dependencies message (#28)
-
Bump to v0.51.0, update method name (#31)
-
accept optional U+03BB (λ) after % in kiro and q CLIs (#44)