[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-aws-labs-cao-provider":3,"mdc-o1c3ax-key":36,"related-repo-aws-labs-cao-provider":1300,"related-org-aws-labs-cao-provider":1399},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":32,"sourceUrl":34,"mdContent":35},"cao-provider","create CLI agent providers for CAO","Create a new CLI agent provider for CAO (CLI Agent Orchestrator). Use this skill whenever the user wants to add support for a new CLI-based AI agent (e.g., a new coding assistant CLI), integrate a new provider, or scaffold a provider implementation. Also use when the user asks about the provider architecture, what files to modify, or how providers work in CAO.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"aws-labs","AWS Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Faws-labs.png","awslabs",[13,17,20,23],{"name":14,"slug":15,"type":16},"Automation","automation","tag",{"name":18,"slug":19,"type":16},"CLI","cli",{"name":21,"slug":22,"type":16},"Agents","agents",{"name":24,"slug":25,"type":16},"Engineering","engineering",871,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fcli-agent-orchestrator","2026-07-12T08:37:04.40806",null,164,[],{"repoUrl":27,"stars":26,"forks":30,"topics":33,"description":29},[],"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fcli-agent-orchestrator\u002Ftree\u002FHEAD\u002Fskills\u002Fcao-provider","---\nname: cao-provider\ndescription: Create a new CLI agent provider for CAO (CLI Agent Orchestrator). Use this skill whenever the user wants to add support for a new CLI-based AI agent (e.g., a new coding assistant CLI), integrate a new provider, or scaffold a provider implementation. Also use when the user asks about the provider architecture, what files to modify, or how providers work in CAO.\n---\n\n# CAO Provider Creator\n\nGuide for creating a new CLI agent provider for CLI Agent Orchestrator. A \"provider\" is an adapter that lets CAO interact with a specific CLI-based AI agent through tmux.\n\n## What You're Building\n\nA provider translates between CAO's unified interface and a specific CLI tool's terminal output. It needs to:\n\n1. **Launch** the CLI tool in a tmux window with the right flags\n2. **Detect status** by parsing terminal output (IDLE, PROCESSING, COMPLETED, ERROR, WAITING_USER_ANSWER)\n3. **Extract responses** from the terminal buffer after the agent finishes\n4. **Clean up** when the terminal is deleted\n\n## Before You Start\n\nGather this information about the target CLI:\n\n- What command launches it? (e.g., `claude`, `kiro-cli chat`, `codex`)\n- What does the idle prompt look like? (e.g., `> `, `❯ `, `ask a question`)\n- What does the processing state look like? (e.g., spinner characters, \"Thinking...\")\n- How are responses formatted? (e.g., preceded by `⏺`, inside a box, plain text)\n- Does it support `--dangerously-skip-permissions` or similar flags?\n- Does it have a REPL mode or is it single-shot?\n- How does it handle MCP servers? (CLI flags, config file, agent JSON)\n- Does it use alt-screen (full-screen TUI) or scrollback (inline output)? This fundamentally changes status detection logic — see lesson #16\n- What's the exit command? (`\u002Fexit`, `\u002Fquit`, Ctrl+C)\n\n## Step-by-Step Implementation\n\n### Step 1: Add to ProviderType enum\n\nFile: `src\u002Fcli_agent_orchestrator\u002Fmodels\u002Fprovider.py`\n\n```python\nclass ProviderType(str, Enum):\n    # ... existing providers ...\n    NEW_CLI = \"new_cli\"\n```\n\nThe value string is used everywhere — in API requests, database, config. Use snake_case.\n\n### Step 2: Create the provider class\n\nFile: `src\u002Fcli_agent_orchestrator\u002Fproviders\u002Fnew_cli.py`\n\nRead `references\u002Fprovider-template.md` for the full annotated template. The key sections:\n\n**Regex patterns** — Define at module level, not inside methods. You need patterns for:\n- ANSI code stripping (reuse `r\"\\x1b\\[[0-9;]*m\"`)\n- Idle prompt detection (what the prompt looks like when waiting for input)\n- Processing detection (spinners, \"Thinking...\", progress indicators)\n- Response markers (how agent responses start — e.g., `⏺` for Claude Code)\n- Permission\u002Fconfirmation prompts (if the CLI asks Y\u002Fn questions)\n\n**Status detection priority** — The order in `get_status()` matters. Read `references\u002Flessons-learnt.md` for the critical \"stale buffer\" lesson. The recommended pattern:\n\n```\n1. Strip ANSI codes from terminal output\n2. Check WAITING_USER_ANSWER first (permission prompts need immediate attention)\n3. Check COMPLETED (response marker + idle prompt both present in recent lines)\n4. Check IDLE (just idle prompt, no response marker)\n5. Check PROCESSING (spinner\u002Fthinking indicator in recent lines only)\n6. Default to ERROR\n```\n\n**Message extraction** — Find the last response boundary in the terminal output and extract everything between it and the next prompt. Always strip ANSI codes from the final extracted text.\n\n### Step 3: Register in ProviderManager\n\nFile: `src\u002Fcli_agent_orchestrator\u002Fproviders\u002Fmanager.py`\n\nAdd the import and elif branch:\n\n```python\nfrom cli_agent_orchestrator.providers.new_cli import NewCliProvider\n\n# In create_provider():\nelif provider_type == ProviderType.NEW_CLI.value:\n    provider = NewCliProvider(\n        terminal_id, tmux_session, tmux_window, agent_profile, allowed_tools\n    )\n```\n\n### Step 4: Add to PROVIDERS_REQUIRING_WORKSPACE_ACCESS\n\nFile: `src\u002Fcli_agent_orchestrator\u002Fcli\u002Fcommands\u002Flaunch.py`\n\nIf the provider executes code or accesses the filesystem, add it:\n\n```python\nPROVIDERS_REQUIRING_WORKSPACE_ACCESS = {\n    # ... existing ...\n    \"new_cli\",\n}\n```\n\n### Step 5: Tool restriction enforcement\n\nThere are three approaches depending on the CLI's capabilities. Read `docs\u002Ftool-restrictions.md` for full context.\n\n**Hard enforcement via CLI flags** (e.g., Claude Code, Copilot CLI): Add the provider to `TOOL_MAPPING` in `src\u002Fcli_agent_orchestrator\u002Futils\u002Ftool_mapping.py` to translate CAO vocabulary to native tool names.\n\n**Hard enforcement via agent JSON** (e.g., Kiro CLI): The CLI reads `allowedTools` from the agent profile. No `TOOL_MAPPING` entry needed — CAO passes vocabulary directly.\n\n**Soft enforcement via system prompt** (e.g., Kimi CLI, Codex): No native restriction mechanism. CAO prepends restriction instructions to the system prompt. No `TOOL_MAPPING` entry needed.\n\nOnly add a `TOOL_MAPPING` entry if the CLI has its own native tool names that differ from CAO's vocabulary.\n\n### Step 6: Handle startup prompts\n\nMany CLIs show cascading prompts on first launch (workspace trust, permission bypass, terms acceptance). Handle these in `initialize()` or a dedicated `_handle_startup_prompts()` method using a polling loop — not a single check. See `references\u002Flessons-learnt.md` #17 for the stabilization loop pattern. Also consider shell warm-up (#14) and TERM variable compatibility (#15).\n\n### Step 7: Write unit tests\n\nFile: `test\u002Fproviders\u002Ftest_new_cli_unit.py`\n\nRead `references\u002Ftest-guide.md` for the full test structure. Minimum coverage:\n\n1. **Initialization** — successful start, shell timeout, CLI timeout, agent profiles\n2. **Status detection** — IDLE, PROCESSING, COMPLETED, WAITING_USER_ANSWER, ERROR, empty output\n3. **Message extraction** — successful extraction, edge cases, error handling\n4. **Regex patterns** — verify each pattern matches expected terminal output\n5. **Edge cases** — ANSI codes, Unicode, long outputs, multiple responses\n\nUse `unittest.mock.patch` to mock `tmux_client`. Create fixture files in `test\u002Fproviders\u002Ffixtures\u002F`.\n\n### Step 8: Write e2e tests\n\nAdd test classes to existing e2e test files and a fixture in `test\u002Fe2e\u002Fconftest.py`. Read `references\u002Ftest-guide.md` for the full list of e2e test classes to add.\n\n### Step 9: Validate with assign + handoff orchestration\n\nThis is the canonical multi-agent e2e test. It exercises assign (non-blocking), handoff (blocking), send_message (async inbox), and status detection under concurrent load. Use the `examples\u002Fassign\u002F` profiles:\n\n```bash\ncao install examples\u002Fassign\u002Fdata_analyst.md\ncao install examples\u002Fassign\u002Freport_generator.md\ncao install examples\u002Fassign\u002Fanalysis_supervisor.md\ncao launch --agents analysis_supervisor --provider new_cli --auto-approve\n```\n\n**Test flow:** Supervisor assigns 3x data_analyst workers in parallel + handoff 1x report_generator (blocking) → analysts send_message results back to supervisor → supervisor combines template + results into final report.\n\nIf any step fails, investigate:\n- **Assign fails:** Status detection not recognizing IDLE after analyst finishes, or per-directory lock conflict (see lesson #19)\n- **Handoff times out:** COMPLETED not detected — check stale buffer (lesson #1) or alt-screen detection (lesson #16)\n- **send_message not delivered:** Supervisor not reaching IDLE state, blocking message delivery — check startup prompt loop (lesson #17)\n- **Concurrent failures:** Race conditions in shared config files (lesson #19) or TERM env issues (lesson #15)\n\nSee `test\u002Fe2e\u002Ftest_assign.py` for the automated version. Reference: https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fcli-agent-orchestrator\u002Ftree\u002Ffeature\u002Fkimi-cli\u002Fexamples\u002Fassign\n\n### Step 10: Documentation\n\nCreate `docs\u002Fnew-cli.md` with prerequisites, launch examples, agent profile format, known limitations, and troubleshooting. Update `README.md` provider table and `CHANGELOG.md`.\n\n## File Checklist\n\nWhen your provider is complete, verify you've touched all these files:\n\n- [ ] `src\u002Fcli_agent_orchestrator\u002Fmodels\u002Fprovider.py` — ProviderType enum\n- [ ] `src\u002Fcli_agent_orchestrator\u002Fproviders\u002Fnew_cli.py` — Provider class\n- [ ] `src\u002Fcli_agent_orchestrator\u002Fproviders\u002Fmanager.py` — Import + elif branch\n- [ ] `src\u002Fcli_agent_orchestrator\u002Fcli\u002Fcommands\u002Flaunch.py` — PROVIDERS_REQUIRING_WORKSPACE_ACCESS\n- [ ] `src\u002Fcli_agent_orchestrator\u002Futils\u002Ftool_mapping.py` — TOOL_MAPPING (only if CLI needs translation)\n- [ ] `test\u002Fproviders\u002Ftest_new_cli_unit.py` — Unit tests\n- [ ] `test\u002Fproviders\u002Ffixtures\u002Fnew_cli_*.txt` — Test fixtures\n- [ ] `test\u002Fe2e\u002Fconftest.py` — require_new_cli fixture\n- [ ] `test\u002Fe2e\u002Ftest_*.py` — E2E test classes\n- [ ] `docs\u002Fnew-cli.md` — Provider documentation\n- [ ] `README.md` — Provider table\n- [ ] `CHANGELOG.md` — New provider entry\n",{"data":37,"body":38},{"name":4,"description":6},{"type":39,"children":40},"root",[41,50,56,63,68,114,120,125,250,256,263,274,314,319,325,335,348,358,400,426,436,446,452,462,467,535,541,551,556,595,601,614,640,665,682,694,700,728,734,744,756,807,836,842,862,868,881,979,989,994,1037,1058,1064,1092,1098,1103,1294],{"type":42,"tag":43,"props":44,"children":46},"element","h1",{"id":45},"cao-provider-creator",[47],{"type":48,"value":49},"text","CAO Provider Creator",{"type":42,"tag":51,"props":52,"children":53},"p",{},[54],{"type":48,"value":55},"Guide for creating a new CLI agent provider for CLI Agent Orchestrator. A \"provider\" is an adapter that lets CAO interact with a specific CLI-based AI agent through tmux.",{"type":42,"tag":57,"props":58,"children":60},"h2",{"id":59},"what-youre-building",[61],{"type":48,"value":62},"What You're Building",{"type":42,"tag":51,"props":64,"children":65},{},[66],{"type":48,"value":67},"A provider translates between CAO's unified interface and a specific CLI tool's terminal output. It needs to:",{"type":42,"tag":69,"props":70,"children":71},"ol",{},[72,84,94,104],{"type":42,"tag":73,"props":74,"children":75},"li",{},[76,82],{"type":42,"tag":77,"props":78,"children":79},"strong",{},[80],{"type":48,"value":81},"Launch",{"type":48,"value":83}," the CLI tool in a tmux window with the right flags",{"type":42,"tag":73,"props":85,"children":86},{},[87,92],{"type":42,"tag":77,"props":88,"children":89},{},[90],{"type":48,"value":91},"Detect status",{"type":48,"value":93}," by parsing terminal output (IDLE, PROCESSING, COMPLETED, ERROR, WAITING_USER_ANSWER)",{"type":42,"tag":73,"props":95,"children":96},{},[97,102],{"type":42,"tag":77,"props":98,"children":99},{},[100],{"type":48,"value":101},"Extract responses",{"type":48,"value":103}," from the terminal buffer after the agent finishes",{"type":42,"tag":73,"props":105,"children":106},{},[107,112],{"type":42,"tag":77,"props":108,"children":109},{},[110],{"type":48,"value":111},"Clean up",{"type":48,"value":113}," when the terminal is deleted",{"type":42,"tag":57,"props":115,"children":117},{"id":116},"before-you-start",[118],{"type":48,"value":119},"Before You Start",{"type":42,"tag":51,"props":121,"children":122},{},[123],{"type":48,"value":124},"Gather this information about the target CLI:",{"type":42,"tag":126,"props":127,"children":128},"ul",{},[129,158,184,189,202,215,220,225,230],{"type":42,"tag":73,"props":130,"children":131},{},[132,134,141,143,149,150,156],{"type":48,"value":133},"What command launches it? (e.g., ",{"type":42,"tag":135,"props":136,"children":138},"code",{"className":137},[],[139],{"type":48,"value":140},"claude",{"type":48,"value":142},", ",{"type":42,"tag":135,"props":144,"children":146},{"className":145},[],[147],{"type":48,"value":148},"kiro-cli chat",{"type":48,"value":142},{"type":42,"tag":135,"props":151,"children":153},{"className":152},[],[154],{"type":48,"value":155},"codex",{"type":48,"value":157},")",{"type":42,"tag":73,"props":159,"children":160},{},[161,163,169,170,176,177,183],{"type":48,"value":162},"What does the idle prompt look like? (e.g., ",{"type":42,"tag":135,"props":164,"children":166},{"className":165},[],[167],{"type":48,"value":168},"> ",{"type":48,"value":142},{"type":42,"tag":135,"props":171,"children":173},{"className":172},[],[174],{"type":48,"value":175},"❯ ",{"type":48,"value":142},{"type":42,"tag":135,"props":178,"children":180},{"className":179},[],[181],{"type":48,"value":182},"ask a question",{"type":48,"value":157},{"type":42,"tag":73,"props":185,"children":186},{},[187],{"type":48,"value":188},"What does the processing state look like? (e.g., spinner characters, \"Thinking...\")",{"type":42,"tag":73,"props":190,"children":191},{},[192,194,200],{"type":48,"value":193},"How are responses formatted? (e.g., preceded by ",{"type":42,"tag":135,"props":195,"children":197},{"className":196},[],[198],{"type":48,"value":199},"⏺",{"type":48,"value":201},", inside a box, plain text)",{"type":42,"tag":73,"props":203,"children":204},{},[205,207,213],{"type":48,"value":206},"Does it support ",{"type":42,"tag":135,"props":208,"children":210},{"className":209},[],[211],{"type":48,"value":212},"--dangerously-skip-permissions",{"type":48,"value":214}," or similar flags?",{"type":42,"tag":73,"props":216,"children":217},{},[218],{"type":48,"value":219},"Does it have a REPL mode or is it single-shot?",{"type":42,"tag":73,"props":221,"children":222},{},[223],{"type":48,"value":224},"How does it handle MCP servers? (CLI flags, config file, agent JSON)",{"type":42,"tag":73,"props":226,"children":227},{},[228],{"type":48,"value":229},"Does it use alt-screen (full-screen TUI) or scrollback (inline output)? This fundamentally changes status detection logic — see lesson #16",{"type":42,"tag":73,"props":231,"children":232},{},[233,235,241,242,248],{"type":48,"value":234},"What's the exit command? (",{"type":42,"tag":135,"props":236,"children":238},{"className":237},[],[239],{"type":48,"value":240},"\u002Fexit",{"type":48,"value":142},{"type":42,"tag":135,"props":243,"children":245},{"className":244},[],[246],{"type":48,"value":247},"\u002Fquit",{"type":48,"value":249},", Ctrl+C)",{"type":42,"tag":57,"props":251,"children":253},{"id":252},"step-by-step-implementation",[254],{"type":48,"value":255},"Step-by-Step Implementation",{"type":42,"tag":257,"props":258,"children":260},"h3",{"id":259},"step-1-add-to-providertype-enum",[261],{"type":48,"value":262},"Step 1: Add to ProviderType enum",{"type":42,"tag":51,"props":264,"children":265},{},[266,268],{"type":48,"value":267},"File: ",{"type":42,"tag":135,"props":269,"children":271},{"className":270},[],[272],{"type":48,"value":273},"src\u002Fcli_agent_orchestrator\u002Fmodels\u002Fprovider.py",{"type":42,"tag":275,"props":276,"children":281},"pre",{"className":277,"code":278,"language":279,"meta":280,"style":280},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","class ProviderType(str, Enum):\n    # ... existing providers ...\n    NEW_CLI = \"new_cli\"\n","python","",[282],{"type":42,"tag":135,"props":283,"children":284},{"__ignoreMap":280},[285,296,305],{"type":42,"tag":286,"props":287,"children":290},"span",{"class":288,"line":289},"line",1,[291],{"type":42,"tag":286,"props":292,"children":293},{},[294],{"type":48,"value":295},"class ProviderType(str, Enum):\n",{"type":42,"tag":286,"props":297,"children":299},{"class":288,"line":298},2,[300],{"type":42,"tag":286,"props":301,"children":302},{},[303],{"type":48,"value":304},"    # ... existing providers ...\n",{"type":42,"tag":286,"props":306,"children":308},{"class":288,"line":307},3,[309],{"type":42,"tag":286,"props":310,"children":311},{},[312],{"type":48,"value":313},"    NEW_CLI = \"new_cli\"\n",{"type":42,"tag":51,"props":315,"children":316},{},[317],{"type":48,"value":318},"The value string is used everywhere — in API requests, database, config. Use snake_case.",{"type":42,"tag":257,"props":320,"children":322},{"id":321},"step-2-create-the-provider-class",[323],{"type":48,"value":324},"Step 2: Create the provider class",{"type":42,"tag":51,"props":326,"children":327},{},[328,329],{"type":48,"value":267},{"type":42,"tag":135,"props":330,"children":332},{"className":331},[],[333],{"type":48,"value":334},"src\u002Fcli_agent_orchestrator\u002Fproviders\u002Fnew_cli.py",{"type":42,"tag":51,"props":336,"children":337},{},[338,340,346],{"type":48,"value":339},"Read ",{"type":42,"tag":135,"props":341,"children":343},{"className":342},[],[344],{"type":48,"value":345},"references\u002Fprovider-template.md",{"type":48,"value":347}," for the full annotated template. The key sections:",{"type":42,"tag":51,"props":349,"children":350},{},[351,356],{"type":42,"tag":77,"props":352,"children":353},{},[354],{"type":48,"value":355},"Regex patterns",{"type":48,"value":357}," — Define at module level, not inside methods. You need patterns for:",{"type":42,"tag":126,"props":359,"children":360},{},[361,373,378,383,395],{"type":42,"tag":73,"props":362,"children":363},{},[364,366,372],{"type":48,"value":365},"ANSI code stripping (reuse ",{"type":42,"tag":135,"props":367,"children":369},{"className":368},[],[370],{"type":48,"value":371},"r\"\\x1b\\[[0-9;]*m\"",{"type":48,"value":157},{"type":42,"tag":73,"props":374,"children":375},{},[376],{"type":48,"value":377},"Idle prompt detection (what the prompt looks like when waiting for input)",{"type":42,"tag":73,"props":379,"children":380},{},[381],{"type":48,"value":382},"Processing detection (spinners, \"Thinking...\", progress indicators)",{"type":42,"tag":73,"props":384,"children":385},{},[386,388,393],{"type":48,"value":387},"Response markers (how agent responses start — e.g., ",{"type":42,"tag":135,"props":389,"children":391},{"className":390},[],[392],{"type":48,"value":199},{"type":48,"value":394}," for Claude Code)",{"type":42,"tag":73,"props":396,"children":397},{},[398],{"type":48,"value":399},"Permission\u002Fconfirmation prompts (if the CLI asks Y\u002Fn questions)",{"type":42,"tag":51,"props":401,"children":402},{},[403,408,410,416,418,424],{"type":42,"tag":77,"props":404,"children":405},{},[406],{"type":48,"value":407},"Status detection priority",{"type":48,"value":409}," — The order in ",{"type":42,"tag":135,"props":411,"children":413},{"className":412},[],[414],{"type":48,"value":415},"get_status()",{"type":48,"value":417}," matters. Read ",{"type":42,"tag":135,"props":419,"children":421},{"className":420},[],[422],{"type":48,"value":423},"references\u002Flessons-learnt.md",{"type":48,"value":425}," for the critical \"stale buffer\" lesson. The recommended pattern:",{"type":42,"tag":275,"props":427,"children":431},{"className":428,"code":430,"language":48},[429],"language-text","1. Strip ANSI codes from terminal output\n2. Check WAITING_USER_ANSWER first (permission prompts need immediate attention)\n3. Check COMPLETED (response marker + idle prompt both present in recent lines)\n4. Check IDLE (just idle prompt, no response marker)\n5. Check PROCESSING (spinner\u002Fthinking indicator in recent lines only)\n6. Default to ERROR\n",[432],{"type":42,"tag":135,"props":433,"children":434},{"__ignoreMap":280},[435],{"type":48,"value":430},{"type":42,"tag":51,"props":437,"children":438},{},[439,444],{"type":42,"tag":77,"props":440,"children":441},{},[442],{"type":48,"value":443},"Message extraction",{"type":48,"value":445}," — Find the last response boundary in the terminal output and extract everything between it and the next prompt. Always strip ANSI codes from the final extracted text.",{"type":42,"tag":257,"props":447,"children":449},{"id":448},"step-3-register-in-providermanager",[450],{"type":48,"value":451},"Step 3: Register in ProviderManager",{"type":42,"tag":51,"props":453,"children":454},{},[455,456],{"type":48,"value":267},{"type":42,"tag":135,"props":457,"children":459},{"className":458},[],[460],{"type":48,"value":461},"src\u002Fcli_agent_orchestrator\u002Fproviders\u002Fmanager.py",{"type":42,"tag":51,"props":463,"children":464},{},[465],{"type":48,"value":466},"Add the import and elif branch:",{"type":42,"tag":275,"props":468,"children":470},{"className":277,"code":469,"language":279,"meta":280,"style":280},"from cli_agent_orchestrator.providers.new_cli import NewCliProvider\n\n# In create_provider():\nelif provider_type == ProviderType.NEW_CLI.value:\n    provider = NewCliProvider(\n        terminal_id, tmux_session, tmux_window, agent_profile, allowed_tools\n    )\n",[471],{"type":42,"tag":135,"props":472,"children":473},{"__ignoreMap":280},[474,482,491,499,508,517,526],{"type":42,"tag":286,"props":475,"children":476},{"class":288,"line":289},[477],{"type":42,"tag":286,"props":478,"children":479},{},[480],{"type":48,"value":481},"from cli_agent_orchestrator.providers.new_cli import NewCliProvider\n",{"type":42,"tag":286,"props":483,"children":484},{"class":288,"line":298},[485],{"type":42,"tag":286,"props":486,"children":488},{"emptyLinePlaceholder":487},true,[489],{"type":48,"value":490},"\n",{"type":42,"tag":286,"props":492,"children":493},{"class":288,"line":307},[494],{"type":42,"tag":286,"props":495,"children":496},{},[497],{"type":48,"value":498},"# In create_provider():\n",{"type":42,"tag":286,"props":500,"children":502},{"class":288,"line":501},4,[503],{"type":42,"tag":286,"props":504,"children":505},{},[506],{"type":48,"value":507},"elif provider_type == ProviderType.NEW_CLI.value:\n",{"type":42,"tag":286,"props":509,"children":511},{"class":288,"line":510},5,[512],{"type":42,"tag":286,"props":513,"children":514},{},[515],{"type":48,"value":516},"    provider = NewCliProvider(\n",{"type":42,"tag":286,"props":518,"children":520},{"class":288,"line":519},6,[521],{"type":42,"tag":286,"props":522,"children":523},{},[524],{"type":48,"value":525},"        terminal_id, tmux_session, tmux_window, agent_profile, allowed_tools\n",{"type":42,"tag":286,"props":527,"children":529},{"class":288,"line":528},7,[530],{"type":42,"tag":286,"props":531,"children":532},{},[533],{"type":48,"value":534},"    )\n",{"type":42,"tag":257,"props":536,"children":538},{"id":537},"step-4-add-to-providers_requiring_workspace_access",[539],{"type":48,"value":540},"Step 4: Add to PROVIDERS_REQUIRING_WORKSPACE_ACCESS",{"type":42,"tag":51,"props":542,"children":543},{},[544,545],{"type":48,"value":267},{"type":42,"tag":135,"props":546,"children":548},{"className":547},[],[549],{"type":48,"value":550},"src\u002Fcli_agent_orchestrator\u002Fcli\u002Fcommands\u002Flaunch.py",{"type":42,"tag":51,"props":552,"children":553},{},[554],{"type":48,"value":555},"If the provider executes code or accesses the filesystem, add it:",{"type":42,"tag":275,"props":557,"children":559},{"className":277,"code":558,"language":279,"meta":280,"style":280},"PROVIDERS_REQUIRING_WORKSPACE_ACCESS = {\n    # ... existing ...\n    \"new_cli\",\n}\n",[560],{"type":42,"tag":135,"props":561,"children":562},{"__ignoreMap":280},[563,571,579,587],{"type":42,"tag":286,"props":564,"children":565},{"class":288,"line":289},[566],{"type":42,"tag":286,"props":567,"children":568},{},[569],{"type":48,"value":570},"PROVIDERS_REQUIRING_WORKSPACE_ACCESS = {\n",{"type":42,"tag":286,"props":572,"children":573},{"class":288,"line":298},[574],{"type":42,"tag":286,"props":575,"children":576},{},[577],{"type":48,"value":578},"    # ... existing ...\n",{"type":42,"tag":286,"props":580,"children":581},{"class":288,"line":307},[582],{"type":42,"tag":286,"props":583,"children":584},{},[585],{"type":48,"value":586},"    \"new_cli\",\n",{"type":42,"tag":286,"props":588,"children":589},{"class":288,"line":501},[590],{"type":42,"tag":286,"props":591,"children":592},{},[593],{"type":48,"value":594},"}\n",{"type":42,"tag":257,"props":596,"children":598},{"id":597},"step-5-tool-restriction-enforcement",[599],{"type":48,"value":600},"Step 5: Tool restriction enforcement",{"type":42,"tag":51,"props":602,"children":603},{},[604,606,612],{"type":48,"value":605},"There are three approaches depending on the CLI's capabilities. Read ",{"type":42,"tag":135,"props":607,"children":609},{"className":608},[],[610],{"type":48,"value":611},"docs\u002Ftool-restrictions.md",{"type":48,"value":613}," for full context.",{"type":42,"tag":51,"props":615,"children":616},{},[617,622,624,630,632,638],{"type":42,"tag":77,"props":618,"children":619},{},[620],{"type":48,"value":621},"Hard enforcement via CLI flags",{"type":48,"value":623}," (e.g., Claude Code, Copilot CLI): Add the provider to ",{"type":42,"tag":135,"props":625,"children":627},{"className":626},[],[628],{"type":48,"value":629},"TOOL_MAPPING",{"type":48,"value":631}," in ",{"type":42,"tag":135,"props":633,"children":635},{"className":634},[],[636],{"type":48,"value":637},"src\u002Fcli_agent_orchestrator\u002Futils\u002Ftool_mapping.py",{"type":48,"value":639}," to translate CAO vocabulary to native tool names.",{"type":42,"tag":51,"props":641,"children":642},{},[643,648,650,656,658,663],{"type":42,"tag":77,"props":644,"children":645},{},[646],{"type":48,"value":647},"Hard enforcement via agent JSON",{"type":48,"value":649}," (e.g., Kiro CLI): The CLI reads ",{"type":42,"tag":135,"props":651,"children":653},{"className":652},[],[654],{"type":48,"value":655},"allowedTools",{"type":48,"value":657}," from the agent profile. No ",{"type":42,"tag":135,"props":659,"children":661},{"className":660},[],[662],{"type":48,"value":629},{"type":48,"value":664}," entry needed — CAO passes vocabulary directly.",{"type":42,"tag":51,"props":666,"children":667},{},[668,673,675,680],{"type":42,"tag":77,"props":669,"children":670},{},[671],{"type":48,"value":672},"Soft enforcement via system prompt",{"type":48,"value":674}," (e.g., Kimi CLI, Codex): No native restriction mechanism. CAO prepends restriction instructions to the system prompt. No ",{"type":42,"tag":135,"props":676,"children":678},{"className":677},[],[679],{"type":48,"value":629},{"type":48,"value":681}," entry needed.",{"type":42,"tag":51,"props":683,"children":684},{},[685,687,692],{"type":48,"value":686},"Only add a ",{"type":42,"tag":135,"props":688,"children":690},{"className":689},[],[691],{"type":48,"value":629},{"type":48,"value":693}," entry if the CLI has its own native tool names that differ from CAO's vocabulary.",{"type":42,"tag":257,"props":695,"children":697},{"id":696},"step-6-handle-startup-prompts",[698],{"type":48,"value":699},"Step 6: Handle startup prompts",{"type":42,"tag":51,"props":701,"children":702},{},[703,705,711,713,719,721,726],{"type":48,"value":704},"Many CLIs show cascading prompts on first launch (workspace trust, permission bypass, terms acceptance). Handle these in ",{"type":42,"tag":135,"props":706,"children":708},{"className":707},[],[709],{"type":48,"value":710},"initialize()",{"type":48,"value":712}," or a dedicated ",{"type":42,"tag":135,"props":714,"children":716},{"className":715},[],[717],{"type":48,"value":718},"_handle_startup_prompts()",{"type":48,"value":720}," method using a polling loop — not a single check. See ",{"type":42,"tag":135,"props":722,"children":724},{"className":723},[],[725],{"type":48,"value":423},{"type":48,"value":727}," #17 for the stabilization loop pattern. Also consider shell warm-up (#14) and TERM variable compatibility (#15).",{"type":42,"tag":257,"props":729,"children":731},{"id":730},"step-7-write-unit-tests",[732],{"type":48,"value":733},"Step 7: Write unit tests",{"type":42,"tag":51,"props":735,"children":736},{},[737,738],{"type":48,"value":267},{"type":42,"tag":135,"props":739,"children":741},{"className":740},[],[742],{"type":48,"value":743},"test\u002Fproviders\u002Ftest_new_cli_unit.py",{"type":42,"tag":51,"props":745,"children":746},{},[747,748,754],{"type":48,"value":339},{"type":42,"tag":135,"props":749,"children":751},{"className":750},[],[752],{"type":48,"value":753},"references\u002Ftest-guide.md",{"type":48,"value":755}," for the full test structure. Minimum coverage:",{"type":42,"tag":69,"props":757,"children":758},{},[759,769,779,788,797],{"type":42,"tag":73,"props":760,"children":761},{},[762,767],{"type":42,"tag":77,"props":763,"children":764},{},[765],{"type":48,"value":766},"Initialization",{"type":48,"value":768}," — successful start, shell timeout, CLI timeout, agent profiles",{"type":42,"tag":73,"props":770,"children":771},{},[772,777],{"type":42,"tag":77,"props":773,"children":774},{},[775],{"type":48,"value":776},"Status detection",{"type":48,"value":778}," — IDLE, PROCESSING, COMPLETED, WAITING_USER_ANSWER, ERROR, empty output",{"type":42,"tag":73,"props":780,"children":781},{},[782,786],{"type":42,"tag":77,"props":783,"children":784},{},[785],{"type":48,"value":443},{"type":48,"value":787}," — successful extraction, edge cases, error handling",{"type":42,"tag":73,"props":789,"children":790},{},[791,795],{"type":42,"tag":77,"props":792,"children":793},{},[794],{"type":48,"value":355},{"type":48,"value":796}," — verify each pattern matches expected terminal output",{"type":42,"tag":73,"props":798,"children":799},{},[800,805],{"type":42,"tag":77,"props":801,"children":802},{},[803],{"type":48,"value":804},"Edge cases",{"type":48,"value":806}," — ANSI codes, Unicode, long outputs, multiple responses",{"type":42,"tag":51,"props":808,"children":809},{},[810,812,818,820,826,828,834],{"type":48,"value":811},"Use ",{"type":42,"tag":135,"props":813,"children":815},{"className":814},[],[816],{"type":48,"value":817},"unittest.mock.patch",{"type":48,"value":819}," to mock ",{"type":42,"tag":135,"props":821,"children":823},{"className":822},[],[824],{"type":48,"value":825},"tmux_client",{"type":48,"value":827},". Create fixture files in ",{"type":42,"tag":135,"props":829,"children":831},{"className":830},[],[832],{"type":48,"value":833},"test\u002Fproviders\u002Ffixtures\u002F",{"type":48,"value":835},".",{"type":42,"tag":257,"props":837,"children":839},{"id":838},"step-8-write-e2e-tests",[840],{"type":48,"value":841},"Step 8: Write e2e tests",{"type":42,"tag":51,"props":843,"children":844},{},[845,847,853,855,860],{"type":48,"value":846},"Add test classes to existing e2e test files and a fixture in ",{"type":42,"tag":135,"props":848,"children":850},{"className":849},[],[851],{"type":48,"value":852},"test\u002Fe2e\u002Fconftest.py",{"type":48,"value":854},". Read ",{"type":42,"tag":135,"props":856,"children":858},{"className":857},[],[859],{"type":48,"value":753},{"type":48,"value":861}," for the full list of e2e test classes to add.",{"type":42,"tag":257,"props":863,"children":865},{"id":864},"step-9-validate-with-assign-handoff-orchestration",[866],{"type":48,"value":867},"Step 9: Validate with assign + handoff orchestration",{"type":42,"tag":51,"props":869,"children":870},{},[871,873,879],{"type":48,"value":872},"This is the canonical multi-agent e2e test. It exercises assign (non-blocking), handoff (blocking), send_message (async inbox), and status detection under concurrent load. Use the ",{"type":42,"tag":135,"props":874,"children":876},{"className":875},[],[877],{"type":48,"value":878},"examples\u002Fassign\u002F",{"type":48,"value":880}," profiles:",{"type":42,"tag":275,"props":882,"children":886},{"className":883,"code":884,"language":885,"meta":280,"style":280},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","cao install examples\u002Fassign\u002Fdata_analyst.md\ncao install examples\u002Fassign\u002Freport_generator.md\ncao install examples\u002Fassign\u002Fanalysis_supervisor.md\ncao launch --agents analysis_supervisor --provider new_cli --auto-approve\n","bash",[887],{"type":42,"tag":135,"props":888,"children":889},{"__ignoreMap":280},[890,910,926,942],{"type":42,"tag":286,"props":891,"children":892},{"class":288,"line":289},[893,899,905],{"type":42,"tag":286,"props":894,"children":896},{"style":895},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[897],{"type":48,"value":898},"cao",{"type":42,"tag":286,"props":900,"children":902},{"style":901},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[903],{"type":48,"value":904}," install",{"type":42,"tag":286,"props":906,"children":907},{"style":901},[908],{"type":48,"value":909}," examples\u002Fassign\u002Fdata_analyst.md\n",{"type":42,"tag":286,"props":911,"children":912},{"class":288,"line":298},[913,917,921],{"type":42,"tag":286,"props":914,"children":915},{"style":895},[916],{"type":48,"value":898},{"type":42,"tag":286,"props":918,"children":919},{"style":901},[920],{"type":48,"value":904},{"type":42,"tag":286,"props":922,"children":923},{"style":901},[924],{"type":48,"value":925}," examples\u002Fassign\u002Freport_generator.md\n",{"type":42,"tag":286,"props":927,"children":928},{"class":288,"line":307},[929,933,937],{"type":42,"tag":286,"props":930,"children":931},{"style":895},[932],{"type":48,"value":898},{"type":42,"tag":286,"props":934,"children":935},{"style":901},[936],{"type":48,"value":904},{"type":42,"tag":286,"props":938,"children":939},{"style":901},[940],{"type":48,"value":941}," examples\u002Fassign\u002Fanalysis_supervisor.md\n",{"type":42,"tag":286,"props":943,"children":944},{"class":288,"line":501},[945,949,954,959,964,969,974],{"type":42,"tag":286,"props":946,"children":947},{"style":895},[948],{"type":48,"value":898},{"type":42,"tag":286,"props":950,"children":951},{"style":901},[952],{"type":48,"value":953}," launch",{"type":42,"tag":286,"props":955,"children":956},{"style":901},[957],{"type":48,"value":958}," --agents",{"type":42,"tag":286,"props":960,"children":961},{"style":901},[962],{"type":48,"value":963}," analysis_supervisor",{"type":42,"tag":286,"props":965,"children":966},{"style":901},[967],{"type":48,"value":968}," --provider",{"type":42,"tag":286,"props":970,"children":971},{"style":901},[972],{"type":48,"value":973}," new_cli",{"type":42,"tag":286,"props":975,"children":976},{"style":901},[977],{"type":48,"value":978}," --auto-approve\n",{"type":42,"tag":51,"props":980,"children":981},{},[982,987],{"type":42,"tag":77,"props":983,"children":984},{},[985],{"type":48,"value":986},"Test flow:",{"type":48,"value":988}," Supervisor assigns 3x data_analyst workers in parallel + handoff 1x report_generator (blocking) → analysts send_message results back to supervisor → supervisor combines template + results into final report.",{"type":42,"tag":51,"props":990,"children":991},{},[992],{"type":48,"value":993},"If any step fails, investigate:",{"type":42,"tag":126,"props":995,"children":996},{},[997,1007,1017,1027],{"type":42,"tag":73,"props":998,"children":999},{},[1000,1005],{"type":42,"tag":77,"props":1001,"children":1002},{},[1003],{"type":48,"value":1004},"Assign fails:",{"type":48,"value":1006}," Status detection not recognizing IDLE after analyst finishes, or per-directory lock conflict (see lesson #19)",{"type":42,"tag":73,"props":1008,"children":1009},{},[1010,1015],{"type":42,"tag":77,"props":1011,"children":1012},{},[1013],{"type":48,"value":1014},"Handoff times out:",{"type":48,"value":1016}," COMPLETED not detected — check stale buffer (lesson #1) or alt-screen detection (lesson #16)",{"type":42,"tag":73,"props":1018,"children":1019},{},[1020,1025],{"type":42,"tag":77,"props":1021,"children":1022},{},[1023],{"type":48,"value":1024},"send_message not delivered:",{"type":48,"value":1026}," Supervisor not reaching IDLE state, blocking message delivery — check startup prompt loop (lesson #17)",{"type":42,"tag":73,"props":1028,"children":1029},{},[1030,1035],{"type":42,"tag":77,"props":1031,"children":1032},{},[1033],{"type":48,"value":1034},"Concurrent failures:",{"type":48,"value":1036}," Race conditions in shared config files (lesson #19) or TERM env issues (lesson #15)",{"type":42,"tag":51,"props":1038,"children":1039},{},[1040,1042,1048,1050],{"type":48,"value":1041},"See ",{"type":42,"tag":135,"props":1043,"children":1045},{"className":1044},[],[1046],{"type":48,"value":1047},"test\u002Fe2e\u002Ftest_assign.py",{"type":48,"value":1049}," for the automated version. Reference: ",{"type":42,"tag":1051,"props":1052,"children":1056},"a",{"href":1053,"rel":1054},"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fcli-agent-orchestrator\u002Ftree\u002Ffeature\u002Fkimi-cli\u002Fexamples\u002Fassign",[1055],"nofollow",[1057],{"type":48,"value":1053},{"type":42,"tag":257,"props":1059,"children":1061},{"id":1060},"step-10-documentation",[1062],{"type":48,"value":1063},"Step 10: Documentation",{"type":42,"tag":51,"props":1065,"children":1066},{},[1067,1069,1075,1077,1083,1085,1091],{"type":48,"value":1068},"Create ",{"type":42,"tag":135,"props":1070,"children":1072},{"className":1071},[],[1073],{"type":48,"value":1074},"docs\u002Fnew-cli.md",{"type":48,"value":1076}," with prerequisites, launch examples, agent profile format, known limitations, and troubleshooting. Update ",{"type":42,"tag":135,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":48,"value":1082},"README.md",{"type":48,"value":1084}," provider table and ",{"type":42,"tag":135,"props":1086,"children":1088},{"className":1087},[],[1089],{"type":48,"value":1090},"CHANGELOG.md",{"type":48,"value":835},{"type":42,"tag":57,"props":1093,"children":1095},{"id":1094},"file-checklist",[1096],{"type":48,"value":1097},"File Checklist",{"type":42,"tag":51,"props":1099,"children":1100},{},[1101],{"type":48,"value":1102},"When your provider is complete, verify you've touched all these files:",{"type":42,"tag":126,"props":1104,"children":1107},{"className":1105},[1106],"contains-task-list",[1108,1127,1142,1157,1172,1187,1202,1218,1233,1249,1264,1279],{"type":42,"tag":73,"props":1109,"children":1112},{"className":1110},[1111],"task-list-item",[1113,1118,1120,1125],{"type":42,"tag":1114,"props":1115,"children":1117},"input",{"disabled":487,"type":1116},"checkbox",[],{"type":48,"value":1119}," ",{"type":42,"tag":135,"props":1121,"children":1123},{"className":1122},[],[1124],{"type":48,"value":273},{"type":48,"value":1126}," — ProviderType enum",{"type":42,"tag":73,"props":1128,"children":1130},{"className":1129},[1111],[1131,1134,1135,1140],{"type":42,"tag":1114,"props":1132,"children":1133},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1136,"children":1138},{"className":1137},[],[1139],{"type":48,"value":334},{"type":48,"value":1141}," — Provider class",{"type":42,"tag":73,"props":1143,"children":1145},{"className":1144},[1111],[1146,1149,1150,1155],{"type":42,"tag":1114,"props":1147,"children":1148},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1151,"children":1153},{"className":1152},[],[1154],{"type":48,"value":461},{"type":48,"value":1156}," — Import + elif branch",{"type":42,"tag":73,"props":1158,"children":1160},{"className":1159},[1111],[1161,1164,1165,1170],{"type":42,"tag":1114,"props":1162,"children":1163},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1166,"children":1168},{"className":1167},[],[1169],{"type":48,"value":550},{"type":48,"value":1171}," — PROVIDERS_REQUIRING_WORKSPACE_ACCESS",{"type":42,"tag":73,"props":1173,"children":1175},{"className":1174},[1111],[1176,1179,1180,1185],{"type":42,"tag":1114,"props":1177,"children":1178},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1181,"children":1183},{"className":1182},[],[1184],{"type":48,"value":637},{"type":48,"value":1186}," — TOOL_MAPPING (only if CLI needs translation)",{"type":42,"tag":73,"props":1188,"children":1190},{"className":1189},[1111],[1191,1194,1195,1200],{"type":42,"tag":1114,"props":1192,"children":1193},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1196,"children":1198},{"className":1197},[],[1199],{"type":48,"value":743},{"type":48,"value":1201}," — Unit tests",{"type":42,"tag":73,"props":1203,"children":1205},{"className":1204},[1111],[1206,1209,1210,1216],{"type":42,"tag":1114,"props":1207,"children":1208},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1211,"children":1213},{"className":1212},[],[1214],{"type":48,"value":1215},"test\u002Fproviders\u002Ffixtures\u002Fnew_cli_*.txt",{"type":48,"value":1217}," — Test fixtures",{"type":42,"tag":73,"props":1219,"children":1221},{"className":1220},[1111],[1222,1225,1226,1231],{"type":42,"tag":1114,"props":1223,"children":1224},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1227,"children":1229},{"className":1228},[],[1230],{"type":48,"value":852},{"type":48,"value":1232}," — require_new_cli fixture",{"type":42,"tag":73,"props":1234,"children":1236},{"className":1235},[1111],[1237,1240,1241,1247],{"type":42,"tag":1114,"props":1238,"children":1239},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1242,"children":1244},{"className":1243},[],[1245],{"type":48,"value":1246},"test\u002Fe2e\u002Ftest_*.py",{"type":48,"value":1248}," — E2E test classes",{"type":42,"tag":73,"props":1250,"children":1252},{"className":1251},[1111],[1253,1256,1257,1262],{"type":42,"tag":1114,"props":1254,"children":1255},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1258,"children":1260},{"className":1259},[],[1261],{"type":48,"value":1074},{"type":48,"value":1263}," — Provider documentation",{"type":42,"tag":73,"props":1265,"children":1267},{"className":1266},[1111],[1268,1271,1272,1277],{"type":42,"tag":1114,"props":1269,"children":1270},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1273,"children":1275},{"className":1274},[],[1276],{"type":48,"value":1082},{"type":48,"value":1278}," — Provider table",{"type":42,"tag":73,"props":1280,"children":1282},{"className":1281},[1111],[1283,1286,1287,1292],{"type":42,"tag":1114,"props":1284,"children":1285},{"disabled":487,"type":1116},[],{"type":48,"value":1119},{"type":42,"tag":135,"props":1288,"children":1290},{"className":1289},[],[1291],{"type":48,"value":1090},{"type":48,"value":1293}," — New provider entry",{"type":42,"tag":1295,"props":1296,"children":1297},"style",{},[1298],{"type":48,"value":1299},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1301,"total":1398},[1302,1321,1334,1348,1362,1373,1387],{"slug":1303,"name":1303,"fn":1304,"description":1305,"org":1306,"tags":1307,"stars":26,"repoUrl":27,"updatedAt":1320},"add-app-to-server","add interactive UI to MCP servers","This skill should be used when the user asks to \"add an app to my MCP server\", \"add UI to my MCP server\", \"add a view to my MCP tool\", \"enrich MCP tools with UI\", \"add interactive UI to existing server\", \"add MCP Apps to my server\", or needs to add interactive UI capabilities to an existing MCP server that already has tools. Provides guidance for analyzing existing tools and adding MCP Apps UI resources.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1308,1311,1314,1317],{"name":1309,"slug":1310,"type":16},"Frontend","frontend",{"name":1312,"slug":1313,"type":16},"MCP","mcp",{"name":1315,"slug":1316,"type":16},"Plugin Development","plugin-development",{"name":1318,"slug":1319,"type":16},"UI Components","ui-components","2026-07-12T08:41:40.4008",{"slug":1322,"name":1322,"fn":1323,"description":1324,"org":1325,"tags":1326,"stars":26,"repoUrl":27,"updatedAt":1333},"agui-author","emit interactive dashboard UI components","Author live dashboard UI from an agent via the `emit_ui` MCP tool. Emit one of six allow-listed components (approval_card, choice_prompt, diff_summary, progress, metric, agent_card) with JSON props and it renders in any AG-UI client watching the fleet. Use when you want the operator to see a decision, a diff, or a status readout instead of scrolling terminal text. Arbitrary HTML\u002Fmarkup is refused.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1327,1328,1331,1332],{"name":21,"slug":22,"type":16},{"name":1329,"slug":1330,"type":16},"Dashboards","dashboards",{"name":1312,"slug":1313,"type":16},{"name":1318,"slug":1319,"type":16},"2026-07-22T05:35:50.851108",{"slug":1335,"name":1335,"fn":1336,"description":1337,"org":1338,"tags":1339,"stars":26,"repoUrl":27,"updatedAt":1347},"cao-agent-routing","route tasks to appropriate CAO agents","Find and select the best installed CAO agent profile for a task before delegating with assign or handoff. Use when a supervisor needs to route coding, documentation, infrastructure, review, research, or other specialist work and the user has not already chosen an agent profile.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1340,1341,1344],{"name":21,"slug":22,"type":16},{"name":1342,"slug":1343,"type":16},"AWS","aws",{"name":1345,"slug":1346,"type":16},"Orchestration","orchestration","2026-07-25T05:56:34.255071",{"slug":1349,"name":1349,"fn":1350,"description":1351,"org":1352,"tags":1353,"stars":26,"repoUrl":27,"updatedAt":1361},"cao-learning","report task outcomes and distill lessons","Report task outcomes and distill lessons so the team improves across runs — report_outcome after each unit of work, retrospector handoffs at natural boundaries, and applying injected lessons. Use in workflows that run repeatedly over similar work items. Requires memory.learning_enabled; degrade silently when the tools report disabled.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1354,1357,1358],{"name":1355,"slug":1356,"type":16},"Best Practices","best-practices",{"name":24,"slug":25,"type":16},{"name":1359,"slug":1360,"type":16},"Operations","operations","2026-07-29T06:00:28.147989",{"slug":1363,"name":1363,"fn":1364,"description":1365,"org":1366,"tags":1367,"stars":26,"repoUrl":27,"updatedAt":1372},"cao-mcp-apps","operate CAO MCP application surfaces","Enable, operate, and extend CAO's MCP Apps surface — the host-rendered fleet dashboard visible inside MCP App hosts (Claude Desktop, ChatGPT, VS Code Copilot, Goose, Postman). Use when the user says \"enable MCP Apps in CAO\", \"the ui:\u002F\u002Fcao views aren't rendering\", \"rebuild MCP Apps bundles\", \"add a new ui:\u002F\u002Fcao\u002F* view\", or \"configure the MCP Apps OAuth scope layer\". Operates on the CAO_MCP_APPS_ENABLED surface and cao_mcp_apps\u002F build system. Not for the localhost:9889 browser dashboard, not for plugins, providers, or session management.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1368,1369,1370,1371],{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"name":1312,"slug":1313,"type":16},{"name":1318,"slug":1319,"type":16},"2026-07-22T05:35:52.952289",{"slug":1374,"name":1374,"fn":1375,"description":1376,"org":1377,"tags":1378,"stars":26,"repoUrl":27,"updatedAt":1386},"cao-memory","manage durable agent memory and preferences","Store, recall, and forget durable facts with CAO memory — user preferences, project conventions, decisions, and corrections that should persist across sessions and agents. Use proactively to check memory before asking the user, and to save anything worth remembering. Distinct from any provider-native memory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1379,1380,1383],{"name":21,"slug":22,"type":16},{"name":1381,"slug":1382,"type":16},"Memory","memory",{"name":1384,"slug":1385,"type":16},"Productivity","productivity","2026-07-12T08:37:03.180421",{"slug":1388,"name":1388,"fn":1389,"description":1390,"org":1391,"tags":1392,"stars":26,"repoUrl":27,"updatedAt":1397},"cao-plugin","scaffold CAO agent plugins","Create a new CAO (CLI Agent Orchestrator) plugin. Use this skill whenever the user wants to add a plugin that reacts to CAO lifecycle or messaging events, scaffold a plugin package, understand plugin requirements, or integrate an external system (Discord, Slack, dashboards, logging, metrics) with CAO. Also use when the user asks what plugin events are available, how plugin discovery works, or how to install a plugin into a CAO environment.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1393,1394,1395,1396],{"name":21,"slug":22,"type":16},{"name":14,"slug":15,"type":16},{"name":18,"slug":19,"type":16},{"name":1315,"slug":1316,"type":16},"2026-07-12T08:36:49.784639",16,{"items":1400,"total":1576},[1401,1420,1441,1451,1464,1477,1487,1497,1518,1533,1548,1561],{"slug":1402,"name":1402,"fn":1403,"description":1404,"org":1405,"tags":1406,"stars":1417,"repoUrl":1418,"updatedAt":1419},"agentcore-investigation","investigate Bedrock AgentCore runtime sessions","Investigate Bedrock AgentCore runtime sessions via CloudWatch Logs Insights — resolve session\u002Ftrace IDs, query OTEL spans, filter noise, build timelines. Use when debugging AgentCore agent sessions, tracing tool calls, or analyzing latency.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1407,1408,1411,1414],{"name":1342,"slug":1343,"type":16},{"name":1409,"slug":1410,"type":16},"Debugging","debugging",{"name":1412,"slug":1413,"type":16},"Logs","logs",{"name":1415,"slug":1416,"type":16},"Observability","observability",9427,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fmcp","2026-07-12T08:37:22.601527",{"slug":1421,"name":1422,"fn":1423,"description":1424,"org":1425,"tags":1426,"stars":1417,"repoUrl":1418,"updatedAt":1440},"amazon-aurora-dsql","amazon aurora dsql","build applications with Aurora DSQL","Build with Aurora DSQL — manage schemas, execute queries, handle migrations, diagnose query plans, load data, and develop applications with a serverless, distributed SQL database. Covers IAM auth, multi-tenant patterns, MySQL-to-DSQL and PostgreSQL-to-DSQL schema conversion, FK replacement code generation, OCC retry patterns, ORM migration (Django\u002FHibernate\u002FRails), DDL operations, query plan explainability, SQL compatibility validation, and bulk data loading. Triggers on phrases like: DSQL, Aurora DSQL, create DSQL table, DSQL schema, migrate to DSQL, distributed SQL database, serverless PostgreSQL-compatible database, DSQL query plan, DSQL EXPLAIN ANALYZE, why is my DSQL query slow, DSQL foreign key, DSQL OCC retry, DSQL multi-region, load into DSQL, load CSV into DSQL, bulk load DSQL, aurora-dsql-loader.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1427,1430,1431,1434,1437],{"name":1428,"slug":1429,"type":16},"Aurora","aurora",{"name":1342,"slug":1343,"type":16},{"name":1432,"slug":1433,"type":16},"Database","database",{"name":1435,"slug":1436,"type":16},"Serverless","serverless",{"name":1438,"slug":1439,"type":16},"SQL","sql","2026-07-12T08:36:45.053393",{"slug":1442,"name":1443,"fn":1423,"description":1424,"org":1444,"tags":1445,"stars":1417,"repoUrl":1418,"updatedAt":1450},"aurora-dsql","aurora dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1446,1447,1448,1449],{"name":1342,"slug":1343,"type":16},{"name":1432,"slug":1433,"type":16},{"name":1435,"slug":1436,"type":16},{"name":1438,"slug":1439,"type":16},"2026-07-12T08:36:42.694299",{"slug":1452,"name":1453,"fn":1423,"description":1424,"org":1454,"tags":1455,"stars":1417,"repoUrl":1418,"updatedAt":1463},"aws-dsql","aws dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1456,1457,1458,1461,1462],{"name":1342,"slug":1343,"type":16},{"name":1432,"slug":1433,"type":16},{"name":1459,"slug":1460,"type":16},"Migration","migration",{"name":1435,"slug":1436,"type":16},{"name":1438,"slug":1439,"type":16},"2026-07-12T08:36:38.584057",{"slug":1465,"name":1466,"fn":1423,"description":1424,"org":1467,"tags":1468,"stars":1417,"repoUrl":1418,"updatedAt":1476},"distributed-postgres","distributed postgres",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1469,1470,1471,1474,1475],{"name":1342,"slug":1343,"type":16},{"name":1432,"slug":1433,"type":16},{"name":1472,"slug":1473,"type":16},"PostgreSQL","postgresql",{"name":1435,"slug":1436,"type":16},{"name":1438,"slug":1439,"type":16},"2026-07-12T08:36:46.530743",{"slug":1478,"name":1479,"fn":1423,"description":1424,"org":1480,"tags":1481,"stars":1417,"repoUrl":1418,"updatedAt":1486},"distributed-sql","distributed sql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1482,1483,1484,1485],{"name":1342,"slug":1343,"type":16},{"name":1432,"slug":1433,"type":16},{"name":1435,"slug":1436,"type":16},{"name":1438,"slug":1439,"type":16},"2026-07-12T08:36:48.104182",{"slug":1488,"name":1488,"fn":1423,"description":1424,"org":1489,"tags":1490,"stars":1417,"repoUrl":1418,"updatedAt":1496},"dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1491,1492,1493,1494,1495],{"name":1342,"slug":1343,"type":16},{"name":1432,"slug":1433,"type":16},{"name":1459,"slug":1460,"type":16},{"name":1435,"slug":1436,"type":16},{"name":1438,"slug":1439,"type":16},"2026-07-12T08:36:36.374512",{"slug":1498,"name":1498,"fn":1499,"description":1500,"org":1501,"tags":1502,"stars":1515,"repoUrl":1516,"updatedAt":1517},"cost-efficiency-analyzer","analyze cost efficiency and expenses","Analyzes cost structure, cost efficiency, and expense management from P&L data. Use when the user asks about costs, expenses, COGS, operating expenses, cost ratios, cost control, spending efficiency, margin compression from cost side, or wants to understand where money is going. Also use for \"are we spending too much\", \"cost breakdown\", \"expense analysis\", or \"how efficient are our operations\". NOT for revenue or top-line analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1503,1506,1509,1512],{"name":1504,"slug":1505,"type":16},"Accounting","accounting",{"name":1507,"slug":1508,"type":16},"Analytics","analytics",{"name":1510,"slug":1511,"type":16},"Cost Optimization","cost-optimization",{"name":1513,"slug":1514,"type":16},"Finance","finance",3176,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fagentcore-samples","2026-07-12T08:40:03.29555",{"slug":1519,"name":1519,"fn":1520,"description":1521,"org":1522,"tags":1523,"stars":1515,"repoUrl":1516,"updatedAt":1532},"executive-financial-briefing","generate executive financial briefings","Generates a concise executive-level financial briefing or summary suitable for a CEO, CFO, or board presentation. Use when the user asks for a summary, briefing, executive summary, board update, financial overview, financial health check, or \"how is the business doing\". Covers the full P&L picture in one page. Also use for \"give me the highlights\", \"what do I need to know\", or \"quick financial update\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1524,1525,1526,1529],{"name":1342,"slug":1343,"type":16},{"name":1513,"slug":1514,"type":16},{"name":1527,"slug":1528,"type":16},"Management","management",{"name":1530,"slug":1531,"type":16},"Reporting","reporting","2026-07-12T08:40:02.066471",{"slug":1534,"name":1534,"fn":1535,"description":1536,"org":1537,"tags":1538,"stars":1515,"repoUrl":1516,"updatedAt":1547},"multi-quarter-trend-analysis","analyze multi-quarter financial trends","Analyzes financial trends across multiple quarters by comparing P&L metrics over time. Use when the user wants to see trends, patterns, trajectories, or directional movement across 3 or more quarters. Also use for \"how are we trending\", \"show me the trend\", \"track performance over time\", \"quarter over quarter comparison across all quarters\", or any multi-period longitudinal analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1539,1540,1541,1544],{"name":1507,"slug":1508,"type":16},{"name":1513,"slug":1514,"type":16},{"name":1542,"slug":1543,"type":16},"Financial Statements","financial-statements",{"name":1545,"slug":1546,"type":16},"Variance Analysis","variance-analysis","2026-07-12T08:40:00.79141",{"slug":1549,"name":1549,"fn":1550,"description":1551,"org":1552,"tags":1553,"stars":1515,"repoUrl":1516,"updatedAt":1560},"pdf","process and manipulate PDF documents","Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text\u002Ftables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting\u002Fdecrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1554,1555,1558],{"name":14,"slug":15,"type":16},{"name":1556,"slug":1557,"type":16},"Documents","documents",{"name":1559,"slug":1549,"type":16},"PDF","2026-07-12T08:41:44.135656",{"slug":1562,"name":1562,"fn":1563,"description":1564,"org":1565,"tags":1566,"stars":1515,"repoUrl":1516,"updatedAt":1575},"quarterly-kpi-calculator","calculate quarterly financial KPIs","Calculates quarterly financial KPIs from P&L data. P&L figures can be provided directly by the user or fetched from the financial data MCP server. Use when the user wants KPI calculations such as Gross Margin %, EBITDA Margin %, Operating Expense Ratio, or Revenue Growth % QoQ. Also use for quarterly performance review, P&L analysis, or interpreting financial ratios against benchmarks.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1567,1568,1571,1572],{"name":1504,"slug":1505,"type":16},{"name":1569,"slug":1570,"type":16},"Data Analysis","data-analysis",{"name":1513,"slug":1514,"type":16},{"name":1573,"slug":1574,"type":16},"KPI","kpi","2026-07-12T08:39:59.54971",150]