What version of Kimi Code is running?
0.42.0
Which open platform/subscription were you using?
Kimi Platform (API key · platform.kimi.ai)
Which model were you using?
kimi-k3
What platform is your computer?
Darwin 25.6.0 arm64 arm
What issue are you seeing?
A UserPromptSubmit hook that denies submission (to display a result and skip the model call) shows the result, but the TUI never finishes the pending interaction on its own. A following prompt stays queued until I press Ctrl-S ("steer immediately"). Both exit-0 structured denial and exit-2 denial reproduce it; changing the hook output form does not resolve the stall.
Source-level findings (verified against 0.42.0 commit 6954d2c8bf94a5c7fc29cc6ae35b15d042cc4dcb and current main d3dc5945548d3353a5e6cfc457a3a8cf84d7da71):
- The engine does emit
prompt.completed with reason: "blocked", but the SDK filters it out before it reaches the TUI: prompt.completed is in DROPPED_DOMAIN_EVENT_TYPES (packages/node-sdk/src/v2/event-mapper.ts, entry at L38 on main, filter at L68).
- The blocked path publishes completion and returns before
loop.submit, so no engine turn starts or ends (packages/agent-core-v2/src/agent/prompt/promptService.ts L547–552).
- The TUI finalizes an interaction on
turn.ended (apps/kimi-code/src/tui/controllers/session-event-handler.ts L369–391); the hook.result handler (L594–617) renders the result without finalizing.
Net: on the hook-denial path the TUI gets the display event but neither a forwarded prompt.completed nor a turn.ended, so it never returns to idle.
What steps can reproduce the bug?
- Add this rule to
~/.kimi-code/config.toml, then start a new interactive kimi session:
[[hooks]]
event = "UserPromptSubmit"
matcher = "^hook-stall$"
command = "printf '%s\\n' 'Hook handled this prompt; model submission skipped.' >&2; exit 2"
- Submit
hook-stall. The hook result is displayed and model submission is denied.
- Submit a nonmatching prompt, such as
Reply with OK. It stays pending instead of being processed.
- Press Ctrl-S (“steer immediately”); the following prompt can then proceed.
For the exit-0 variant, replace only command with:
command = '''
printf '%s\n' '{"message":"Hook handled this prompt; model submission skipped.","hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"Handled by hook"}}'
exit 0
'''
Use one variant at a time. The explicit message avoids conflating this with raw JSON display when that field is absent.
What is the expected behavior?
After displaying the hook result and denying submission, the TUI should finish the interaction cleanly, return to idle, and process the next prompt normally without ctrl-s.
Additional information
Related: #3464 (client stalls / invisible completed work, but for compaction/rendering and queueing, not this hook-denial path), #3568 (raw hook JSON when no message field — here the result displays fine; completion stalls with either output form), #3536 (proposed model-visible/terminal-hidden context), PR #929 (suppress allowed hook output while keeping blocking output visible — this is about finishing after that visible blocking result).
Contribution
What version of Kimi Code is running?
0.42.0
Which open platform/subscription were you using?
Kimi Platform (API key · platform.kimi.ai)
Which model were you using?
kimi-k3
What platform is your computer?
Darwin 25.6.0 arm64 arm
What issue are you seeing?
A
UserPromptSubmithook that denies submission (to display a result and skip the model call) shows the result, but the TUI never finishes the pending interaction on its own. A following prompt stays queued until I press Ctrl-S ("steer immediately"). Both exit-0 structured denial and exit-2 denial reproduce it; changing the hook output form does not resolve the stall.Source-level findings (verified against 0.42.0 commit
6954d2c8bf94a5c7fc29cc6ae35b15d042cc4dcband currentmaind3dc5945548d3353a5e6cfc457a3a8cf84d7da71):prompt.completedwithreason: "blocked", but the SDK filters it out before it reaches the TUI:prompt.completedis inDROPPED_DOMAIN_EVENT_TYPES(packages/node-sdk/src/v2/event-mapper.ts, entry at L38 on main, filter at L68).loop.submit, so no engine turn starts or ends (packages/agent-core-v2/src/agent/prompt/promptService.tsL547–552).turn.ended(apps/kimi-code/src/tui/controllers/session-event-handler.tsL369–391); thehook.resulthandler (L594–617) renders the result without finalizing.Net: on the hook-denial path the TUI gets the display event but neither a forwarded
prompt.completednor aturn.ended, so it never returns to idle.What steps can reproduce the bug?
~/.kimi-code/config.toml, then start a new interactivekimisession:hook-stall. The hook result is displayed and model submission is denied.Reply with OK. It stays pending instead of being processed.For the exit-0 variant, replace only
commandwith:Use one variant at a time. The explicit
messageavoids conflating this with raw JSON display when that field is absent.What is the expected behavior?
After displaying the hook result and denying submission, the TUI should finish the interaction cleanly, return to idle, and process the next prompt normally without
ctrl-s.Additional information
Related: #3464 (client stalls / invisible completed work, but for compaction/rendering and queueing, not this hook-denial path), #3568 (raw hook JSON when no
messagefield — here the result displays fine; completion stalls with either output form), #3536 (proposed model-visible/terminal-hidden context), PR #929 (suppress allowed hook output while keeping blocking output visible — this is about finishing after that visible blocking result).Contribution