fix(kiro-cli): emit the standalone hooks format Kiro CLI 3.0 reads - #2609
Merged
Conversation
kiro-cli-hooks.ts was a one-line subclass of the legacy KiroHooks, writing
camelCase hooks into the embedded .kiro/agents/default.json agent config. Kiro's
hooks migration guide states that format does not work in 3.0, so the kiro-cli
hooks output was not merely stale but dead.
Repoint the kiro-cli target at the KiroIdeHooks emitter: both products read the
same standalone {"version": "v1"} file under .kiro/hooks/. The emitter is
parameterized by override key so kiro-cli.hooks still wins over kiro-ide.hooks,
and its static factories now construct via `new this` so the subclass keeps its
own identity — the previous subclass returned KiroHooks instances, which sent
imported overrides to the kiro block instead of kiro-cli.
The legacy embedded writer stays on the deprecated kiro alias. Global scope
follows from the repoint, since the same file exists at ~/.kiro/hooks/.
Part of #2408.
Addresses review findings on PR #2609. The README and supported-tools prose still described kiro-cli as writing hooks into .kiro/agents/default.json, which this PR makes false, and docs/** is embedded into the distributed docs bundle so the error would reach users. Rewrites those paragraphs plus the stale clause in the file-formats hooks intro. Adds the migration guidance the repoint needs: an earlier rulesync left a hooks block in .kiro/agents/default.json that nothing removes (the file is shared with permissions and subagents), and Kiro CLI 2.x reads both formats, so the block has to be deleted by hand or every hook fires twice. Also records that importing those old hooks now needs --targets kiro, and that sessionEnd and cacheTtl have no counterpart in the standalone format. Rounds out the stale comments in src/types/hooks.ts and kiro-paths.ts, replaces the duplicated override-key union with a shared type alias, drops the now single-valued override-key indirection from the legacy writer, and adds tests for prompt hooks, forDeletion identity, the dropped sessionEnd, and the IDE side of the override-key split.
This was referenced Aug 7, 2026
Merged
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/features/hooks/kiro-cli-hooks.tswas a one-line subclass of the legacyKiroHooks, emitting camelCase hooks into the embedded.kiro/agents/default.jsonagent config. Kiro's hooks migration guide states that format "does not work in 3.0", so thekiro-clihooks output was not merely stale — it was dead on the current CLI.This repoints the
kiro-clitarget at theKiroIdeHooksemitter. Both products read the same standalone{"version": "v1", "hooks": [ … ]}file under.kiro/hooks/, per docs/hooks, which is the basis for every judgment call below.kiro-cli.hooksstill wins overkiro-ide.hooksin both directions.new this(...)/this.getSettablePaths(...). Worth calling out: the old subclass did not do this —KiroCliHooks.fromFilereturned aKiroHooksinstance, sotoRulesyncHooksread the override key off the parent and routed importedkiro-clioverrides into thekiroblock. That defect goes away with the rewrite.kiro-ideone:KIRO_IDE_HOOK_EVENTS,command+prompthook types, matcher support, passthrough override events, and global scope (the same file exists at~/.kiro/hooks/, added in CLI 2.13.0).kiroalias, with its now-misleading "Kiro CLI" doc comments corrected. The e2ecache_ttl_secondsround-trip moved tokiro, since that field belongs to the embedded format.One behavior worth naming:
kiro-cliandkiro-idenow write the same.kiro/hooks/rulesync.json. With both targets enabled the shared hooks are identical, but divergent override blocks are last-writer-wins. A distinct filename would be worse — Kiro runs every*.jsonin the directory and both products read the same one, so two files would run every hook twice. This mirrors the existingkiro/kiro-clisharing ofdefault.json, and it is documented in the note.Scope
This fixes the dead-format bug only. It leaves gap 4 of #2408 open — the
~/.kiro/hooksfile-sharing design question is not resolved here, and the argument that this repoint settles it is the re-check comment's own reasoning rather than a maintainer ruling. Gap 2 (the five triggers reachable only through the override block) is likewise untouched: reusingKIRO_IDE_HOOK_EVENTSunchanged is the whole move.Testing
pnpm cicheck(full: code + content)npx vitest run --config vitest.e2e.config.ts src/e2e/e2e-hooks.spec.ts— the matrix asserts exact output paths, sokiro-climoved to the v1 path and into the standalone-format assertion branch, and it was added to the global matrix.kiro-cli-hooks.test.tsrewritten for the v1 format: settable paths, the override key in both directions (including aPostFileSavetrigger that can only survive in the override block), subclass identity, and global scope.pnpm run generate:tablespicked up the new global support for kiro-cli hooks;pnpm dev gitignorereports no change, sincekiro-idealready emits this path.Part of #2408
🤖 Generated with Claude Code