Skip to content

feat: add Kiro (kiro-cli, AWS Kiro IDE) preset and hook installer#1302

Open
Krishnachaitanyakc wants to merge 3 commits into
git-ai-project:mainfrom
Krishnachaitanyakc:feat/kiro-support-584
Open

feat: add Kiro (kiro-cli, AWS Kiro IDE) preset and hook installer#1302
Krishnachaitanyakc wants to merge 3 commits into
git-ai-project:mainfrom
Krishnachaitanyakc:feat/kiro-support-584

Conversation

@Krishnachaitanyakc
Copy link
Copy Markdown
Contributor

@Krishnachaitanyakc Krishnachaitanyakc commented May 7, 2026

Summary

Adds first-class support for AWS Kiro CLI's hook protocol against the post-rewrite agent-preset framework. Closes #584.

This is the CLI integration only (kiro-cli). The Kiro IDE GUI also has a hook system but its JSON payload schema is undocumented; supporting it is intentionally out of scope for v1.

Preset (presets/kiro.rs)

  • Pure parser implementing AgentPreset::parse. Handles preToolUse / postToolUse for fs_write (and the documented write alias) and execute_bash (and the shell alias).
  • Strict event handling: lifecycle events (agentSpawn, userPromptSubmit, stop) AND PascalCase Claude-shaped event names (PreToolUse, PostToolUse) return PresetError rather than fabricating a phantom file-edit checkpoint. Kiro's wire convention is camelCase.
  • Path resolution: relative tool_input.path resolved against cwd; absolute paths pass through unchanged.
  • transcript_source: None for v1 — see "Deferred work" below.

Installer (mdm/agents/kiro.rs)

  • Writes hook entries into a per-agent JSON file at ~/.kiro/agents/default.json per the Kiro agent configuration reference. Kiro's hook system is per-agent rather than global; users with multiple custom agents will need to re-install per-agent or symlink (documented limitation).
  • Idempotent: repeat install with the desired command is a no-op (compared structurally so JSON round-trip whitespace doesn't cause spurious diffs).
  • Token-based ownership matching (is_git_ai_kiro_command): a hypothetical sibling preset like kiro-pro is never misidentified.
  • Uninstall removes only kiro entries, removes emptied event keys (preToolUse: []) AND the empty hooks block; user-defined hooks and other agent settings (name, model, tools) survive.

Tool classification (bash_tool.rs)

  • New Agent::Kiro variant: fs_write / writeFileEdit, execute_bash / shellBash, all else Skip (fs_read/read, use_aws/aws, @server/* MCP tools).

Wiring

  • presets/mod.rs::resolve_preset accepts kiro.
  • mdm/agents/mod.rs::get_all_installers includes KiroInstaller. Detection uses binary_exists("kiro-cli") plus the ~/.kiro dotfile fallback.
  • git_ai_handlers help text lists kiro.
  • AI_AUTHOR_NAMES and is_known_checkpoint_preset learn kiro.

Deferred work (transcript reading)

The issue's original prompt asked for "transcript updating in post-commit to ensure that you have the latest transcript before the final git note is written." Hook-based attribution (covered here) is fully working, but transcript-based prompt extraction is not implemented in this PR for the following reasons:

  1. No transcript_path in hook payloads. The Kiro CLI hooks docs show only hook_event_name, cwd, session_id at top level — no transcript path is surfaced.
  2. Undocumented session storage. Kiro stores conversation history in a SQLite database under ~/.kiro/, keyed by session_id (UUIDs like f2946a26-3735-4b08-8d05-c928010302d5), but the schema is not publicly documented. Reverse-engineering it for v1 would risk breaking on Kiro updates.

A SQLite-based transcript reader can land in a follow-up PR once Kiro documents the schema (or upstream provides an export API). Happy to take pointers if there's a recommended path.

Test plan

  • cargo fmt --check clean
  • cargo clippy --all-targets -- -D warnings clean (no #[allow(...)] annotations added)
  • RUSTDOCFLAGS="-D warnings" cargo doc --no-deps clean
  • 11 preset unit tests (presets::kiro::tests::*) — pre/post for fs_write/write/execute_bash/shell alias coverage, lifecycle event rejection (3 events), unsupported tool rejection (fs_read/read/use_aws/aws/@git/status), PascalCase event name rejection, missing field errors (session_id, cwd), invalid JSON, absolute path passthrough
  • 19 installer unit tests (mdm::agents::kiro::tests::*) — fresh install (s1), idempotency (s2), preserves user agent settings AND user-defined hooks (s3), updates outdated path (s4), dedup (s5), dry-run (s6), creates parent dir (s7); uninstall variants u1-u5 including emptied-event-key removal (u4); error handling e1-e4 (invalid JSON, root-must-be-object, hooks-must-be-object); token-precise ownership matching (substring lookalikes never match)
  • 10 integration tests (tests/integration/kiro.rs) — preset routing for all 4 tool aliases, lifecycle/tool/PascalCase rejection sweeps, 3 E2E flows asserting assert_lines_and_blame and session metadata
  • Full lib test suite passes locally on macOS in daemon mode

Open in Devin Review

Adds first-class support for Kiro CLI's hook protocol against the
post-rewrite agent-preset framework.

Preset (`presets/kiro.rs`):
  - Pure parser implementing `AgentPreset::parse`. Handles
    `preToolUse` / `postToolUse` for `fs_write` (and the `write`
    alias) and `execute_bash` (and the `shell` alias).
  - Strict event handling: lifecycle events (`agentSpawn`,
    `userPromptSubmit`, `stop`) and PascalCase Claude-shaped event
    names return `PresetError` rather than fabricating a phantom
    file-edit checkpoint.
  - Path resolution: relative `tool_input.path` resolved against
    `cwd`; absolute paths pass through unchanged.
  - `transcript_source: None`. Kiro stores conversation history
    in an undocumented SQLite database under `~/.kiro/`; a
    SQLite-based reader can land in a follow-up once the schema
    is documented upstream.

Installer (`mdm/agents/kiro.rs`):
  - Writes hook entries into a per-agent JSON file at
    `~/.kiro/agents/default.json`. Kiro's hook system is per-agent
    rather than global; users with multiple custom agents will
    need to re-install per-agent or symlink (documented limitation).
  - Idempotent — repeat install with the desired command is a
    no-op (compared structurally so JSON round-trip whitespace
    doesn't cause spurious diffs).
  - Token-based ownership matching (`is_git_ai_kiro_command`):
    a hypothetical sibling preset like `kiro-pro` is never
    misidentified.
  - Uninstall removes only kiro entries, removes emptied event
    keys and the empty `hooks` block; user-defined hooks and
    other agent settings (name, model, tools) survive.

Tool classification (`bash_tool.rs`):
  - New `Agent::Kiro` variant. `fs_write` / `write` map to
    `FileEdit`, `execute_bash` / `shell` map to `Bash`, all else
    `Skip`.

Targets the Kiro CLI (`kiro-cli`) only — the IDE GUI hook system
has an undocumented payload schema and is intentionally out of
scope for v1.

Wiring:
  - `presets/mod.rs::resolve_preset` accepts `kiro`.
  - `mdm/agents/mod.rs::get_all_installers` includes
    `KiroInstaller`. Detection uses `binary_exists("kiro-cli")`
    plus the `~/.kiro` dotfile fallback.
  - `git_ai_handlers` help text lists `kiro`.
  - `tests/integration/repos/test_file.rs::AI_AUTHOR_NAMES` and
    `test_repo.rs::is_known_checkpoint_preset` learn `kiro`.

Tests: 11 preset unit tests, 19 installer unit tests, 10
integration tests including 3 full E2E flows asserting
`assert_lines_and_blame`. `cargo fmt --check`, `cargo clippy
--all-targets -- -D warnings`, `RUSTDOCFLAGS=\"-D warnings\"
cargo doc --no-deps`, and the relevant test suites all pass
locally.

Closes git-ai-project#584
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

Live-validation against the installed kiro-cli binary surfaced that
our installer's freshly-generated `~/.kiro/agents/default.json` was
missing the required `name` field. The upstream
`AgentConfigV2025_08_22` struct (in `aws/amazon-q-developer-cli`'s
`crates/agent/src/agent/agent_config/definitions.rs`) declares `name`
as a non-default field, so without it Kiro refuses to deserialize the
agent file and fails to load any of our hooks.

Populate `name: "default"` (matches the file stem and the upstream
`DEFAULT_AGENT_NAME` constant) on first install only — existing user
files with a custom name are preserved.

Tests:
  - s1 now asserts the `name` field is present in the freshly-created
    config.
  - s1b (new) verifies a pre-existing `"name": "my-custom-agent"`
    survives an install round-trip.

Verified end-to-end on macOS with a real `kiro-cli 2.2.2` install:
the generated config now passes a port of upstream's serde schema
(parses cleanly with the upstream `AgentConfigV2025_08_22` struct
fields). The pre-fix config failed with `missing field 'name' at
line 14 column 1`.
Cleanup of an #[ignore]'d test that was used during local
verification of the schema fix. The 31 normal tests already cover
the install path comprehensively.
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.

Is there a plan to support Kiro Agent?

2 participants