Skip to content

Commit 1d8a93c

Browse files
nycjayJason Knasternjbrakeclaude
authored
feat: add Kiro CLI agent support (#958)
* feat: add Kiro CLI agent support Register Kiro CLI (kiro-cli) as a built-in agent with: - Detection via `which kiro-cli` - YOLO mode via `--trust-all-tools` flag - Session resume via `--resume-id` flag - Hook-based status detection via a dedicated agent config file (~/.kiro/agents/aoe-hooks.json) using Kiro's native hook format (lowercase event names, flat {command} objects) - Container config mount for ~/.kiro (syncs agents, steering, prompts, and settings dirs into sandbox) - Kiro CLI installed in the sandbox Docker image Docs updated: README, docs/index.md, docs/guides/sandbox.md. Closes #951 * fix(kiro): wire status hooks for sandbox sessions and isolate kiro-cli side effect Three review fixes from PR #958: 1. Sandboxed Kiro sessions had no hook status volume mount and no per-instance aoe-hooks.json install (the host kiro path was gated on !is_sandboxed but no sandbox branch existed). Add a kiro_hooks special-case alongside hermes_hooks in build_container_config so the sidecar dir is mounted and the agent config is materialized inside the sandbox dir. 2. install_kiro_hooks shelled out to `kiro-cli` unconditionally, which meant cargo test mutated the developer's real default Kiro agent on any machine with kiro-cli installed. Split into pure file IO (install_kiro_hooks) and a separate set_kiro_default_agent_if_builtin that the host install path calls explicitly. 3. Update the stale comment in agents.rs that referred to "until a Kiro-specific hook installer is added"; the installer is here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(kiro): use structured JSON output for default agent detection Switch set_kiro_default_agent_if_builtin from substring-matching plain text output to using `kiro-cli settings --format json`, which returns `null` (unset), `"kiro_default"` (built-in), or `"custom-name"` (user-chosen). Eliminates false matches on agent names containing 'kiro_default' or 'not set' as substrings. Fixes #962 --------- Co-authored-by: Jason Knaster <jason.knaster@infor.com> Co-authored-by: njbrake <nathan@mozilla.ai> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 011001d commit 1d8a93c

10 files changed

Lines changed: 393 additions & 13 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Running one AI agent is easy. Running five of them across different branches, ke
3333

3434
## Features
3535

36-
- **Multi-agent support**: Claude Code, OpenCode, Mistral Vibe, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi.dev, Factory Droid, and Hermes
36+
- **Multi-agent support**: Claude Code, OpenCode, Mistral Vibe, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi.dev, Factory Droid, Hermes, and Kiro CLI
3737
- **TUI app**: visual interface to create, monitor, and manage sessions
3838
- **Web app** (Beta, stabilization in progress): create, monitor, and control your agents from any browser, installable as a PWA ([guide](docs/guides/web-dashboard.md))
3939
- **CLI app**: create, monitor, and control agents from the command line (integrates with tools like OpenClaw)
@@ -112,7 +112,7 @@ Nothing. Sessions are tmux sessions running in the background. Open and close `a
112112

113113
### Which AI tools are supported?
114114

115-
Claude Code, OpenCode, Mistral Vibe, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi.dev, Factory Droid, and Hermes. AoE auto-detects which are installed on your system.
115+
Claude Code, OpenCode, Mistral Vibe, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi.dev, Factory Droid, Hermes, and Kiro CLI. AoE auto-detects which are installed on your system.
116116

117117
### Can I use AoE over SSH?
118118

docker/Dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# aoe-sandbox: Docker image for Agent of Empires sandbox sessions
2-
# This image provides Claude Code, OpenCode, Mistral Vibe, Hermes, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, and Pi in an isolated environment
2+
# This image provides Claude Code, OpenCode, Mistral Vibe, Hermes, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi, and Kiro CLI in an isolated environment
33

44
FROM ubuntu:24.04
55

@@ -58,6 +58,9 @@ RUN npm install -g @github/copilot
5858
# Install Pi (pi.dev)
5959
RUN npm install -g @mariozechner/pi-coding-agent
6060

61+
# Install Kiro CLI (AWS)
62+
RUN curl -fsSL https://cli.kiro.dev/install | bash
63+
6164
# Create directories for credential mounts
6265
RUN mkdir -p /root/.claude \
6366
/root/.config/opencode \
@@ -70,6 +73,7 @@ RUN mkdir -p /root/.claude \
7073
/root/.copilot \
7174
/root/.pi \
7275
/root/.factory \
76+
/root/.kiro \
7377
/root/.ssh
7478

7579
# Allow Claude Code to use --dangerously-skip-permissions as root

docker/Dockerfile.dev

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# aoe-dev-sandbox: Extended sandbox with development tools
22
# Includes: Rust, uv (Python), nvm + Node.js, pnpm, bun, gh (GitHub CLI)
33
# Note: Claude Code, OpenCode, Mistral Vibe, Hermes, Codex CLI, Gemini CLI,
4-
# Cursor CLI, Copilot CLI, and Pi are inherited from the base image
4+
# Cursor CLI, Copilot CLI, Pi, and Kiro CLI are inherited from the base image
55

66
ARG BASE_IMAGE=ghcr.io/njbrake/aoe-sandbox:latest
77
FROM ${BASE_IMAGE}

docs/guides/sandbox.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Overview
44

5-
Docker sandboxing runs your AI coding agents (Claude Code, OpenCode, Mistral Vibe, Hermes, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi) inside isolated Docker containers while maintaining access to your project files and credentials.
5+
Docker sandboxing runs your AI coding agents (Claude Code, OpenCode, Mistral Vibe, Hermes, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi, Kiro CLI) inside isolated Docker containers while maintaining access to your project files and credentials.
66

77
> **Linux users:** AoE also supports [Podman](podman.md) as a daemonless, rootless-friendly alternative to Docker.
88
>
@@ -192,7 +192,7 @@ AOE provides two official sandbox images:
192192

193193
| Image | Description |
194194
|-------|-------------|
195-
| `ghcr.io/njbrake/aoe-sandbox:latest` | Base image with Claude Code, OpenCode, Mistral Vibe, Hermes, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi, git, ripgrep, fzf |
195+
| `ghcr.io/njbrake/aoe-sandbox:latest` | Base image with Claude Code, OpenCode, Mistral Vibe, Hermes, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi, Kiro CLI, git, ripgrep, fzf |
196196
| `ghcr.io/njbrake/aoe-dev-sandbox:latest` | Extended image with additional dev tools |
197197

198198
### Dev Sandbox Tools

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ allowfullscreen
3535

3636
## Supported Agents
3737

38-
Claude Code, OpenCode, Mistral Vibe, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi, Factory Droid, and Hermes. AoE auto-detects which are installed.
38+
Claude Code, OpenCode, Mistral Vibe, Codex CLI, Gemini CLI, Cursor CLI, Copilot CLI, Pi, Factory Droid, Hermes, and Kiro CLI. AoE auto-detects which are installed.
3939

4040
<div class="cta-box">
4141
<p><strong>Ready to get started?</strong></p>

src/agents.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,27 @@ pub const AGENTS: &[AgentDef] = &[
358358
install_hint:
359359
"curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash",
360360
},
361+
AgentDef {
362+
name: "kiro",
363+
binary: "kiro-cli",
364+
aliases: &["kiro-cli"],
365+
detection: DetectionMethod::Which("kiro-cli"),
366+
yolo: Some(YoloMode::CliFlag("--trust-all-tools")),
367+
instruction_flag: None,
368+
set_default_command: false,
369+
detect_status: status_detection::detect_kiro_status,
370+
container_env: &[("KIRO_CONFIG_DIR", "/root/.kiro")],
371+
// Kiro uses a per-agent JSON config (lowercase event names, flat
372+
// {command} objects) rather than the JSON settings.json schema shared
373+
// by Claude/Cursor/Gemini, so hook_config: None and install is
374+
// special-cased like hermes/settl. Status comes from the hook sidecar
375+
// file written by install_kiro_hooks; the pane stub is unused.
376+
hook_config: None,
377+
resume_strategy: ResumeStrategy::Flag("--resume-id"),
378+
host_only: false,
379+
send_keys_enter_delay_ms: 0,
380+
install_hint: "curl -fsSL https://cli.kiro.dev/install | bash",
381+
},
361382
];
362383

363384
/// Look up an agent by canonical name.
@@ -441,6 +462,7 @@ mod tests {
441462
assert_eq!(get_agent("droid").unwrap().binary, "droid");
442463
assert_eq!(get_agent("settl").unwrap().binary, "settl");
443464
assert_eq!(get_agent("hermes").unwrap().binary, "hermes");
465+
assert_eq!(get_agent("kiro").unwrap().binary, "kiro-cli");
444466
}
445467

446468
#[test]
@@ -472,7 +494,7 @@ mod tests {
472494
names,
473495
vec![
474496
"claude", "opencode", "vibe", "codex", "gemini", "cursor", "copilot", "pi",
475-
"droid", "settl", "hermes"
497+
"droid", "settl", "hermes", "kiro"
476498
]
477499
);
478500
}
@@ -494,6 +516,8 @@ mod tests {
494516
assert_eq!(resolve_tool_name("settlers"), Some("settl"));
495517
assert_eq!(resolve_tool_name("catan"), Some("settl"));
496518
assert_eq!(resolve_tool_name("hermes"), Some("hermes"));
519+
assert_eq!(resolve_tool_name("kiro"), Some("kiro"));
520+
assert_eq!(resolve_tool_name("kiro-cli"), Some("kiro"));
497521
assert_eq!(resolve_tool_name(""), Some("claude"));
498522
assert_eq!(resolve_tool_name("agent"), Some("cursor"));
499523
assert_eq!(resolve_tool_name("unknown-tool"), None);
@@ -510,6 +534,7 @@ mod tests {
510534
assert_eq!(settings_index_from_name(Some("droid")), 9);
511535
assert_eq!(settings_index_from_name(Some("settl")), 10);
512536
assert_eq!(settings_index_from_name(Some("hermes")), 11);
537+
assert_eq!(settings_index_from_name(Some("kiro")), 12);
513538

514539
assert_eq!(name_from_settings_index(0), None);
515540
assert_eq!(name_from_settings_index(1), Some("claude"));
@@ -520,6 +545,7 @@ mod tests {
520545
assert_eq!(name_from_settings_index(9), Some("droid"));
521546
assert_eq!(name_from_settings_index(10), Some("settl"));
522547
assert_eq!(name_from_settings_index(11), Some("hermes"));
548+
assert_eq!(name_from_settings_index(12), Some("kiro"));
523549
assert_eq!(name_from_settings_index(99), None);
524550
}
525551

@@ -542,6 +568,7 @@ mod tests {
542568
assert_eq!(send_keys_enter_delay("claude"), 0);
543569
assert_eq!(send_keys_enter_delay("opencode"), 0);
544570
assert_eq!(send_keys_enter_delay("hermes"), 0);
571+
assert_eq!(send_keys_enter_delay("kiro"), 0);
545572
assert_eq!(send_keys_enter_delay("unknown_agent"), 0);
546573
}
547574

@@ -582,6 +609,10 @@ mod tests {
582609
install_hint("hermes"),
583610
Some("curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash")
584611
);
612+
assert_eq!(
613+
install_hint("kiro"),
614+
Some("curl -fsSL https://cli.kiro.dev/install | bash")
615+
);
585616
assert!(install_hint("unknown").is_none());
586617
}
587618
}

0 commit comments

Comments
 (0)