google-gemini / google-gemini/gemini-cli
hooks: `migrate`'s EVENT_MAPPING key is `SubAgentStop`, but Claude Code emits `SubagentStop`
- Dominant language
- TypeScript
- Stars
- 107k
- Forks
- 14.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 45
Description
### Description
`EVENT_MAPPING` in `packages/cli/src/commands/hooks/migrate.ts` keys the sub-agent event as `SubAgentStop`, with a capital `A`:
```js
var EVENT_MAPPING = {
PreToolUse: "BeforeTool",
PostToolUse: "AfterTool",
UserPromptSubmit: "BeforeAgent",
Stop: "AfterAgent",
SubAgentStop: "AfterAgent",
// Gemini doesn't have sub-agents, map to AfterAgent
SessionStart: "SessionStart",
SessionEnd: "SessionEnd",
PreCompact: "PreCompress",
Notification: "Notification"
};
```
Claude Code spells that event **`SubagentStop`** — lowercase `a` — and that is the key it uses in `settings.json`. The mapping key therefore never matches anything a real Claude configuration contains, so a `SubagentStop` hook is silently dropped during migration instead of being mapped to `AfterAgent`.
Grepping the shipped 0.57.0 bundle: `SubAgentStop` appears in three bundle files, `SubagentStop` in none.
The failure is quiet — no warning is printed, and the migrated config simply lacks the hook — so a user who relies on `SubagentStop` will not learn about it until the hook fails to fire.
### Expected behaviour
Key the entry `SubagentStop`. Accepting both spellings would be a forgiving fallback, since the incorrect one has now shipped.
### Steps to reproduce
1. In `~/.claude/settings.json`, define a hook under the `SubagentStop` event.
2. Run `gemini hooks migrate`.
3. The hook is absent from the generated Gemini settings, with no warning.
### Version
`gemini-cli` 0.57.0 (installed via Homebrew). Verified against the shipped bundle: `bundle/gemini-OYYGXMHL.js`.
### Related
Same class as #14724 (`SessionStart` "compress" vs "compact"): a migration mapping whose key does not match what the source product actually emits.
Contributor guide
Research direction
Start in packages/cli/src/commands/hooks/migrate.ts and inspect EVENT_MAPPING, then compare its sub-agent event key with the Claude settings.json spelling described in the issue. Run the documented gemini hooks migrate reproduction with a SubagentStop hook; done means the generated Gemini settings retain it as an AfterAgent hook, without silently dropping it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 86/100