Skip to content

Fix: Skip status detection based message delivery for providers that support input queueing#16

Closed
patricka3125 wants to merge 11 commits into
mainfrom
fix/claude-ignore-status
Closed

Fix: Skip status detection based message delivery for providers that support input queueing#16
patricka3125 wants to merge 11 commits into
mainfrom
fix/claude-ignore-status

Conversation

@patricka3125

Copy link
Copy Markdown
Owner

No description provided.

haofeif and others added 11 commits March 27, 2026 00:46
* docs: add v2.0.0 changelog and clarify Web UI startup instructions

- Add CHANGELOG entry for v2.0.0 covering all changes since v1.1.0:
  3 new providers (Gemini CLI, Kimi CLI, Copilot CLI), Web UI dashboard,
  provider override in agent profiles, auto-inject sender terminal ID,
  security fixes, and dependency bumps.
- Clarify Web UI README section: note that commands assume project root
  directory, add "In a new terminal" hint for step 2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add cross-provider supervisor profile and update example README

The cross-provider example only had worker profiles with provider
overrides but no supervisor profile showing how to use them. Added
cross_provider_supervisor.md and updated README with installation
and usage instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add report_generator_codex and update cross-provider example

- Add report_generator_codex.md with codex provider override
- Update cross_provider_supervisor.md to use report_generator_codex
  for the handoff step, demonstrating 4 providers in one workflow
  (Claude Code, Gemini CLI, Kiro CLI for assign + Codex for handoff)
- Update README with the new profile and installation step

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add kimi_cli/copilot_cli to valid providers, fix supervisor description

- Update README cross-provider section: add kimi_cli and copilot_cli
  to the valid provider values list
- Fix cross_provider_supervisor.md description to include Codex

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add codex/copilot data analysts, clarify pick-and-choose usage

- Add data_analyst_codex.md and data_analyst_copilot_cli.md for full
  provider coverage
- Rewrite cross_provider_supervisor.md to make clear you pick the
  worker profiles matching your installed providers — not all required
- Split README profiles table into Supervisor / Data Analysts / Report
  Generator sections with guidance on selecting the right ones
- Show commented-out install lines so users can uncomment what they need

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: simplify supervisor to 3 default providers, add customization guide

Supervisor now references claude_code, gemini_cli, and kiro_cli by
default (plus report_generator_codex for handoff). README explains how
to customize the supervisor to use other providers like codex or
copilot_cli, and how to create your own cross-provider profiles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add setup steps and example prompt to cross-provider README

Match the structure of examples/assign/README.md: add cao-server start
step, numbered setup instructions, all provider launch variants, and
the example task prompt for the supervisor terminal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: clarify Web UI startup with dev/production options and browser URLs

Restructure the Web UI section into Option A (dev mode) and Option B
(production mode) with explicit "open browser" instructions for each.
Remove duplicated build section. Move remote/SSH instructions to the end.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add agent-context directory to default agent profile directories

cao install copies profiles to ~/.aws/cli-agent-orchestrator/agent-context/
but this directory was not scanned by agent_profiles.py or shown in the
Web UI settings. Add it as 'cao_installed' in the default agent directories
so installed profiles are discoverable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(claude_code): preserve CLAUDE_CODE_USE_BEDROCK env var in tmux sessions

When CAO spawns Claude Code in tmux, it strips all CLAUDE* env vars to
prevent "nested session" errors. This also removes CLAUDE_CODE_USE_BEDROCK,
which is required for Bedrock authentication, causing Claude Code to show
"Not logged in". Preserve this specific var in both tmux.py (env filter)
and claude_code.py (shell unset command).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(claude_code): clarify CLAUDE_CODE_USE_BEDROCK comment — not just Bedrock

The env var is needed for all authentication modes (Bedrock, custom
models, and default Claude Code credentials), not just Bedrock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(readme): clarify Web UI requires cloned repo

Users who installed via `uv tool install` don't have the web/ directory.
Added a note with clone instructions at the top of the Web UI section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add web/README.md, docs/settings.md, and preserve Claude Code auth env vars

- web/README.md: frontend architecture, tech stack, components, data flow
- docs/settings.md: agent directory configuration, settings.json format, API
- README.md: link to new docs, clarify Web UI requires cloned repo
- CHANGELOG.md: update v2.0.0 release date to 2026-03-28
- tmux.py + claude_code.py: preserve all CLAUDE_CODE_USE_* and
  CLAUDE_CODE_SKIP_*_AUTH env vars (Bedrock, Vertex AI, Foundry)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add cross-provider supervisor profile and update example README

The cross-provider example only had worker profiles with provider
overrides but no supervisor profile showing how to use them. Added
cross_provider_supervisor.md and updated README with installation
and usage instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add report_generator_codex and update cross-provider example

- Add report_generator_codex.md with codex provider override
- Update cross_provider_supervisor.md to use report_generator_codex
  for the handoff step, demonstrating 4 providers in one workflow
  (Claude Code, Gemini CLI, Kiro CLI for assign + Codex for handoff)
- Update README with the new profile and installation step

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add kimi_cli/copilot_cli to valid providers, fix supervisor description

- Update README cross-provider section: add kimi_cli and copilot_cli
  to the valid provider values list
- Fix cross_provider_supervisor.md description to include Codex

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add codex/copilot data analysts, clarify pick-and-choose usage

- Add data_analyst_codex.md and data_analyst_copilot_cli.md for full
  provider coverage
- Rewrite cross_provider_supervisor.md to make clear you pick the
  worker profiles matching your installed providers — not all required
- Split README profiles table into Supervisor / Data Analysts / Report
  Generator sections with guidance on selecting the right ones
- Show commented-out install lines so users can uncomment what they need

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: simplify supervisor to 3 default providers, add customization guide

Supervisor now references claude_code, gemini_cli, and kiro_cli by
default (plus report_generator_codex for handoff). README explains how
to customize the supervisor to use other providers like codex or
copilot_cli, and how to create your own cross-provider profiles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add setup steps and example prompt to cross-provider README

Match the structure of examples/assign/README.md: add cao-server start
step, numbered setup instructions, all provider launch variants, and
the example task prompt for the supervisor terminal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: bump version to 2.0.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Bumps [cryptography](https://github.com/pyca/cryptography) from 46.0.5 to 46.0.6.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](pyca/cryptography@46.0.5...46.0.6)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 46.0.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to 2.20.0.
- [Release notes](https://github.com/pygments/pygments/releases)
- [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES)
- [Commits](pygments/pygments@2.19.2...2.20.0)

---
updated-dependencies:
- dependency-name: pygments
  dependency-version: 2.20.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
awslabs#125)

* feat(security): add allowedTools — universal tool restriction across all providers

Add role-based tool restrictions that translate CAO's unified tool vocabulary
(execute_bash, fs_read, fs_write, fs_*, @cao-mcp-server) to each provider's
native enforcement mechanism:

- Q CLI / Kiro CLI: allowedTools in agent JSON (install time)
- Claude Code: --disallowedTools flags alongside --dangerously-skip-permissions
- Copilot CLI: --deny-tool flags override --allow-all
- Gemini CLI: Policy Engine TOML deny rules in ~/.gemini/policies/
- Kimi CLI / Codex: Security system prompt (soft enforcement)

Key changes:
- AgentProfile: add role field (supervisor/developer/reviewer)
- Constants: ROLE_TOOL_DEFAULTS with per-role defaults
- launch.py: --allowed-tools and --yolo CLI flags, confirmation prompt
- New utils/tool_mapping.py: CAO-to-native tool name translation
- All 7 providers: native restriction flags in command builders
- Database: allowed_tools column for cross-provider inheritance
- MCP server: allowed_tools inheritance for handoff/assign
- Built-in profiles: role + allowedTools frontmatter + security constraints
- SECURITY.md: full documentation of tool restriction system
- E2E tests: file-based bash execution proof across all providers

Gemini CLI enforcement uses Policy Engine deny rules (not deprecated
excludeTools) which work even in --yolo mode by completely excluding
denied tools from the model's memory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add tool restrictions documentation

- README.md: add Tool Restrictions section with role defaults, usage
  examples, and provider enforcement table
- docs/tool-restrictions.md: comprehensive guide covering unified CLI
  (--allowed-tools, --yolo), role-based defaults, CAO tool vocabulary,
  resolution order, per-provider behavior matrix, cross-provider
  inheritance, and security recommendations
- docs/agent-profile.md: add role field, allowedTools documentation,
  tool vocabulary reference, and resolution order
- docs/gemini-cli.md: add Tool Restrictions section explaining Policy
  Engine TOML deny rules and why excludeTools was replaced

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: apply black formatting to pass CI code quality checks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: fix isort import ordering in test_allowed_tools.py

Move `from pathlib import Path` to stdlib import group.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(codex): add --yolo flag to bypass approval prompts in tmux sessions

Merges the intent of PR awslabs#105. CAO agents run in non-interactive tmux
sessions where Codex's interactive approval prompts block handoff/assign
flows. The --yolo flag (alias for --dangerously-bypass-approvals-and-sandbox)
mirrors Claude Code's --dangerously-skip-permissions and Gemini CLI's
--yolo flags.

E2E results: 5/8 passed. 3 failures are pre-existing Codex model behavior
issues (timeouts, supervisor not calling MCP tools) unrelated to this change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(e2e): pre-warm uvx cache to prevent MCP startup timeouts

Agent profiles launch cao-mcp-server via uvx --from git+..., which
downloads ~80 packages on a cold cache (~20s). This exceeds Codex's
default 10s MCP startup timeout, causing flaky test failures. Add a
session-scoped fixture that runs uvx once before tests to populate
the cache (<3s on subsequent runs).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tool-restrictions): redesign to opt-in roles + allowedTools system

- Role is a high-level abstraction (named bundle of allowedTools)
- allowedTools is the low-level fine-grained control
- No role + no allowedTools = unrestricted (backward compatible)
- Support custom roles via settings.json "roles" key
- Fix supervisor defaults: add fs_read and fs_list
- Remove DEFAULT_ROLE (no role = unrestricted, not developer)
- Rewrite docs/tool-restrictions.md with clear concept hierarchy
- Update tests for new defaults and opt-in behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tool-restrictions): improve launch prompts, default to developer, deduplicate docs

- Change default when no role/allowedTools set from unrestricted ["*"] to
  developer defaults — secure by default while preserving backward compat
- Add --yolo warning prompt (visible but non-blocking)
- Add "To grant all permissions, re-run with --yolo" hint to normal prompt
- Add "no role set" reminder with docs link when profile lacks role/allowedTools
- Change confirmation text from "Do you trust all the actions in this folder?"
  to "Proceed?" — clearer that it confirms the shown restrictions, not blanket trust
- Deduplicate agent-profile.md: replace duplicated roles/vocabulary/resolution
  tables with brief summary linking to tool-restrictions.md
- Add allowedTools-only example (no role needed) to tool-restrictions.md
- Add "Launch Confirmation Prompt" section with Confirmation vs --yolo comparison
- Add "Example Profiles" section linking to examples directory
- Fix stale supervisor defaults in README.md (add fs_read, fs_list)
- Add "Tool restrictions" bullet to Key Features in README.md
- Add role/allowedTools to all example profiles missing them
- Add Codex allowed_tools e2e tests with xfail for soft enforcement

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): fix black formatting and update launch prompt assertions

- Run black on launch.py to fix formatting
- Update test_launch.py assertions: old "Do you trust all the actions
  in this folder?" → new "Proceed?" prompt text
- Add WARNING assertion for --yolo test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(tool-restrictions): clarify @cao-mcp-server is pass-through, not enforced

Address PR awslabs#125 feedback: make explicit that @cao-mcp-server in
allowedTools is a declarative marker, not translated to native
enforcement flags. MCP tools remain always available. Also add
WebFetch reference link.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(examples): use role only, remove redundant allowedTools

Replace dual role + allowedTools with role-only in all 14 example
profiles. Add inline comment showing the role's default permissions
and pointing to docs/tool-restrictions.md for fine-grained control.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(agent_store): use role only, remove redundant allowedTools

Same cleanup as examples/ — built-in profiles now use role-only with
inline comment showing default permissions. Also fixes stale supervisor
defaults (was missing fs_read, fs_list).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(README): simplify Tool Restrictions section, link to full reference

Replace detailed tables and examples with a brief summary and link
to docs/tool-restrictions.md for the comprehensive reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
awslabs#138)

The latest Kiro CLI defaults to a new TUI whose prompt format
(e.g. "agent · model · ◔ 1%") doesn't match CAO's idle detection
regex, causing a 30s timeout and 500 error on terminal creation.
Adding --legacy-ui restores the old prompt format that CAO can detect.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Bumps [fastmcp](https://github.com/PrefectHQ/fastmcp) from 2.14.5 to 3.2.0.
- [Release notes](https://github.com/PrefectHQ/fastmcp/releases)
- [Changelog](https://github.com/PrefectHQ/fastmcp/blob/main/docs/changelog.mdx)
- [Commits](PrefectHQ/fastmcp@v2.14.5...v3.2.0)

---
updated-dependencies:
- dependency-name: fastmcp
  dependency-version: 3.2.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ion handling (awslabs#140)

* fix(kiro_cli): add new TUI fallback patterns + fix awslabs#137 exception handling

1. New TUI support: Add fallback detection patterns for the new Kiro CLI
   TUI prompt format ("ask a question, or describe a task"). The provider
   still uses --legacy-ui for reliability but now supports both formats
   in get_status() and extract_last_message_from_script().

2. Fix awslabs#137: load_agent_profile() was wrapping FileNotFoundError as
   RuntimeError, but callers (terminal_service, mcp_server) only catch
   FileNotFoundError. This caused assign() to fail for JSON-only agent
   profiles. FileNotFoundError now passes through directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: fix black formatting in test_kiro_cli_unit.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
patricka3125 added a commit that referenced this pull request Apr 24, 2026
* feat(opencode): Phase 1 — foundation primitives for OpenCode CLI provider

- Add ProviderType.OPENCODE_CLI = "opencode_cli" to the provider enum
- Add OPENCODE_CONFIG_DIR / OPENCODE_AGENTS_DIR / OPENCODE_CONFIG_FILE path
  constants pointing at ~/.aws/opencode_cli/
- New OpenCodeAgentConfig Pydantic model (description, mode, permission) that
  serializes to OpenCode-compatible YAML frontmatter via frontmatter.dumps()
- New cao_tools_to_opencode_permission() translator: two-step algorithm from §9
  of the design doc (shorthand expansion + CAO-category → OpenCode tool mapping +
  hardcoded non-vocabulary deny/allow policies)
- New opencode_config.py read-modify-write helper for the shared opencode.json
  (upsert_mcp_server, upsert_agent_tools, remove_agent_tools, read_config,
  write_config)
- Port 5 TUI probe captures into test/providers/fixtures/ (plain + ANSI variants
  for idle-splash, idle-post-completion, processing, completed, permission states)
- 54 new unit tests covering all Phase 1 modules; all 1368 tests pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(opencode): Phase 1 review items — ANSI fixture, model cleanup, guard-rail

Item 1: Replace opencode_cli_processing.ansi.txt with a genuine PROCESSING frame
        re-captured via tmux probe (md5 9cbe2723, distinct from completed frame).
        Add test/providers/fixtures/OPENCODE_FIXTURES.md documenting all fixture
        sources and the remaining idle_post_completion.ansi.txt reuse.

Item 2: Remove dead Pydantic v1 `class Config: exclude_none = True` block from
        OpenCodeAgentConfig — it is a no-op under Pydantic v2.

Item 3: Add inline comment to OpenCodeAgentConfig.permission documenting the
        deliberate Phase 1 type simplification and when to widen it.

Item 4: Replace unreachable `else: result[tool] = "deny"` in
        opencode_permissions.py with `raise AssertionError(...)` so any future
        tool added to ALL_OPENCODE_TOOLS without a policy update fails loudly.

Item 5: Add test_noop_on_completely_missing_file to TestRemoveAgentTools —
        exercises the read_config() skeleton-return path when opencode.json
        does not exist yet.

All 1369 tests pass; mypy/black/isort clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(install): add opencode_cli provider branch with --auto-approve flag

Adds the `opencode_cli` branch to `cao install` (Phase 2):
- writes agent `<name>.md` with YAML frontmatter (description, mode, permission)
  using compose_agent_prompt for the body and cao_tools_to_opencode_permission
  for the per-tool allow/ask/deny map
- `--auto-approve` flag emits `allow` instead of `ask` for permitted tools;
  has no effect on other providers
- if the agent profile declares mcpServers, upserts top-level mcp/tools entries
  (default-deny) and per-agent tool re-enables into opencode.json
- full unit-test coverage in test/cli/commands/test_install_opencode.py
  (fresh install, idempotency, auto-approve, MCP wiring, config preservation,
  safe filename)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(install): apply Phase 2 review polish

- Rename agent_config_oc → agent_config in opencode_cli branch for
  consistency with Kiro/Q/Copilot sibling branches (Item 1)
- Strengthen test_agent_md_has_body: assert sentinel prompt text via
  profile.prompt frontmatter field instead of weak non-empty check (Item 2)
- Bump live smoke-test subprocess timeout 30s → 60s to survive cold-cache
  npm plugin installs on CI (Item 4)

Items 3 (MCP collision coverage already in Phase 1) and 5 (context-file
parent mkdir — out of Phase 2 scope) intentionally not addressed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(providers): add OpenCodeCliProvider (Phase 3)

Implements the opencode_cli runtime provider per §8 of the design doc:
- OpenCodeCliProvider with full BaseProvider interface (initialize,
  get_status, extract_last_message_from_script, exit_cli, cleanup)
- 5-state detection (IDLE/PROCESSING/COMPLETED/WAITING_USER_ANSWER/ERROR)
  with line-level position guard against stale alt-screen esc-interrupt
  remnants (lesson #16)
- COMPLETED vs IDLE-post-completion distinguished by checking for a
  subsequent ▣ token after the last full completion marker
- 120s initialize() timeout for first-run npm install cold-start (§8.2)
- Inline-env launch command with all stability env vars (§5)
- --model flag included only when profile.model is set (§3.1 exception)
- Registered in ProviderManager; "opencode_cli" added to
  PROVIDERS_REQUIRING_WORKSPACE_ACCESS in launch.py
- 43 unit tests at 96% line coverage against Phase 1 fixtures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add Phase 3 OpenCode provider runtime development walkthrough report

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(opencode): Phase 3 review polish — correct report line count, add dual-pattern comment

Item 1: development report corrected 125 → 332 lines for opencode_cli.py.
Item 4: inline comment at extract_last_message_from_script explains why the
unanchored r"┃\s{2}" is used instead of the module-level USER_MESSAGE_PATTERN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(opencode): Phase 4 — e2e test, provider docs, README/CHANGELOG

- test/e2e/conftest.py: add require_opencode fixture (skips if opencode not on PATH)
- test/e2e/test_assign.py: add TestOpenCodeCliAssign with data_analyst, report_generator,
  and assign_with_callback tests covering all four orchestration modes
- docs/opencode-cli.md: new provider doc covering prerequisites, quick start, config
  isolation, permission/tool mapping, MCP wiring, known limitations, troubleshooting
- README.md: add opencode_cli row to provider table + cao launch example
- CHANGELOG.md: add Unreleased entry announcing OpenCode CLI provider

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add Phase 4 OpenCode e2e and docs development walkthrough report

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(opencode): translate CAO mcpServer format to OpenCode's opencode.json format (Phase 3 regression)

CAO profiles store MCP servers with {type: "stdio", command: str, args: list}.
OpenCode's opencode.json requires {type: "local", command: list, enabled: true}.
The install branch was passing raw CAO config directly, causing OpenCode to reject
the config with "Configuration is invalid: Invalid input mcp.cao-mcp-server".

Fix: add translate_mcp_server_config() to opencode_config.py and call it in the
opencode_cli install branch before upsert_mcp_server(). Also translates env→environment.
6 unit tests added for the translator.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(opencode): add --yolo DANGEROUS caveat to permission troubleshooting (Phase 4 review polish)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update Phase 4 report with e2e results and Phase 3 regression fix notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(opencode): native skill discovery via OPENCODE_CONFIG_DIR/skills symlink

At install time, create a skills → SKILLS_DIR symlink under OPENCODE_CONFIG_DIR
so OpenCode auto-discovers CAO skills through its native skill tool (§5.1). Uses
profile.system_prompt or profile.prompt as the lean agent body — the skill catalog
is no longer baked into the OpenCode system prompt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(opencode): handle Nm Ns duration format and extend extraction buffer

Two status/extraction bugs revealed by e2e runs with full system prompts:

1. COMPLETION_MARKER_PATTERN now matches the Nm Ns duration format that
   OpenCode emits for responses that take more than 60 seconds (e.g.
   "1m 8s"). The old pattern only matched the pure-seconds form, causing
   get_status() to stall at PROCESSING indefinitely for longer turns.

2. Add extraction_tail_lines property to BaseProvider (default None) and
   override to 2000 in OpenCodeCliProvider. terminal_service.get_output
   uses this value for the LAST-mode tmux capture so long responses don't
   push the user-message marker (┃  ) beyond the 200-line default window.
   Status-check captures are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(opencode): single capture-pane per get_output call; add wrong-target symlink test

Item 2: Eliminate double capture-pane in get_output(mode=LAST). Previously
the function always captured at 200 lines then recaptured if the provider
declared extraction_tail_lines. Now FULL mode returns after a single capture
at the default depth; LAST mode resolves extract_lines from the provider once
and makes exactly one capture before the retry loop.

Item 1: Add test_warns_and_skips_when_symlink_points_elsewhere to
TestEnsureSkillsSymlink, covering the branch at opencode_config.py:37-42
where the target is a symlink that resolves to a different directory.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(opencode): rename on-disk config directory from opencode_cli to opencode

Change OPENCODE_CONFIG_DIR from ~/.aws/opencode_cli to ~/.aws/opencode in
constants.py; OPENCODE_AGENTS_DIR and OPENCODE_CONFIG_FILE update transitively.
Update all path string references in docs, CHANGELOG, and the constants unit test.
Provider identifier (ProviderType.OPENCODE_CLI.value == "opencode_cli") is unchanged.
Add CHANGELOG migration note for users who need to re-run cao install.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(opencode): fall back to first agent-indented line when user message scrolled off viewport

OpenCode renders in alt-screen mode so the tmux scrollback only holds the current
visible frame (~41 lines, history_size≈2). For long responses the user-message bar
(┃  ) scrolls off the top before extraction runs, causing "No user message found".

When no ┃  is found before the completion marker, scan for the first 5-space-indented
agent line as the left boundary instead of raising. The visible frame already contains
only the current turn's content, so multi-turn disambiguation is not needed here.

Adds unit test test_fallback_extracts_when_user_message_scrolled_off.
e2e: 3/3 PASSED in 161s on port 9888.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(terminal_service): guard build_skill_catalog() call and update skill-delivery comments

Cleanup 1: build_skill_catalog() now runs only when the provider is in
RUNTIME_SKILL_PROMPT_PROVIDERS, skipping the file reads/YAML parsing/Pydantic
validation for providers that deliver skills natively (OpenCode symlink, Kiro
skill:// resources) or via install-time baking (Q, Copilot). The skill_prompt
kwarg at the create_provider call site simplifies to skill_prompt=skill_prompt
since the guard now lives one line above.

Cleanup 2: update comments in the RUNTIME_SKILL_PROMPT_PROVIDERS block and
create_terminal Steps 3b/4 to reflect Phase 5's native OpenCode skill discovery.

Adds two new tests asserting the lazy-call invariant:
- test_build_skill_catalog_called_for_runtime_prompt_provider (call_count == 1)
- test_build_skill_catalog_not_called_for_native_or_baked_provider (parametrized
  over opencode_cli, kiro_cli, q_cli, copilot_cli; assert_not_called)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update Phase 6 dev report with alt-screen extraction fix and cleanup commits

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(opencode): correct extraction_tail_lines docstring + black format + cleanup polish

Item 1: black reformats terminal_service.py line 155 from a three-line expression
to the single 100-char form black prefers.

Item 2: rewrite extraction_tail_lines docstring — the old text claimed responses
push ┃ beyond a 200-line window, which is wrong; OpenCode's alt-screen mode caps
history_size near 2 making the override a no-op. Docstring now accurately describes
the belt-and-braces rationale and cross-references the within-viewport fallback.

Item 3: add single-turn alt-screen assumption comment to the normal extraction path.

Item 4: CHANGELOG migration note gains a rm -rf cleanup hint for pre-release users.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(opencode): correct OPENCODE_DISABLE_MOUSE rationale and add UX callout

- Update design doc stability-env-vars entry: footer patterns (ctrl+p,
  esc interrupt) are pinned and scroll-safe; the completion marker
  (▣ agent · model · Ns) is conversation content and scrolls off,
  preventing COMPLETED detection if mouse reporting is enabled
- Add 'Scrolling enters tmux copy mode' Known Limitations entry in
  opencode-cli.md explaining the trade-off and how to work around it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* untrack out of scope docs

* fix(opencode): align auto-approve, agent ID, and MCP cleanup semantics

Addresses PR 193 review feedback.

- Drop `cao install --auto-approve` and the `auto_approve` arg on the permission
  translator. CAO owns the permission decision, so `cao_tools_to_opencode_permission`
  now emits only `allow` or `deny`. `cao launch --auto-approve` retains its
  repo-wide meaning (skip CAO's confirmation prompt) and no longer has a
  provider-specific reinterpretation.
- Remove stale `agent.<id>.tools` entries when a profile is reinstalled without
  `mcpServers` so revoked MCP grants do not persist.
- Introduce `to_opencode_agent_id()` and use it consistently for the installed
  `.md` filename and the `agent.<id>.tools` key in `opencode.json`, keeping both
  aligned with the runtime `opencode --agent` argument for slash-containing
  profile names.
- Strip phase numbers and design-doc section references from shipped source
  files and the provider doc per reviewer request.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(opencode): drop reference to removed design doc from changelog

Addresses review comment: the design doc link in the Unreleased entry
referred to a file that is not included in this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(opencode): scope extraction_tail_lines to OpenCodeCliProvider

The property was opencode-specific but lived on BaseProvider, which meant
every provider carried an attribute it had no use for. Remove it from the
base class, keep it as a provider-local property on OpenCodeCliProvider,
and have terminal_service.get_output read it via a getattr capability
check so the base class stays agnostic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(opencode): close codecov gaps in cli provider and permission translator

Adds four tests to cover lines flagged as missing on the codecov report:

- get_status ERROR fallback for non-empty output with no recognized marker
- extract_last_message_from_script residual ``┃`` line + blank-line
  branches when raw_response contains leftover bar-prefixed lines
- extract_last_message_from_script empty-response ValueError
- cao_tools_to_opencode_permission AssertionError when a tool appears in
  ALL_OPENCODE_TOOLS without a matching policy

Brings opencode_cli.py and opencode_permissions.py to 100% patch coverage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(opencode): mark provider experimental — single-agent flows only

Add a warning badge to docs/opencode-cli.md and tag the README provider
table row, both linking the post-settle inbox-delivery deadlock tracked
in awslabs#203. Multi-agent flows are not yet reliable on opencode_cli; this
signals the constraint to evaluators before they hit it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: haofeif <56006724+haofeif@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants