fix: Escape key reliably interrupts agent chat sessions#130
fix: Escape key reliably interrupts agent chat sessions#130danshapiro wants to merge 6 commits intomainfrom
Conversation
…d picker pane warning The skill previously said FRESHELL_TOKEN="<auth-token>" with no hint where to find it — now reads it from .env where it actually lives. Also documents picker panes as ephemeral and warns against targeting them for layout mutations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… of focus
Move the Escape-to-interrupt handler from the <textarea> onKeyDown in
ChatComposer up to a container-level onKeyDown on the AgentChatView
wrapper <div> with tabIndex={-1}. This ensures Escape works regardless
of which element inside the agent-chat pane has focus.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Now that AgentChatView handles Escape at the container level, the textarea-level Escape handler in ChatComposer is redundant. Remove it to avoid double-firing. The Stop button still uses onInterrupt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c0df0adace
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (e.key === 'Escape' && isRunning) { | ||
| e.preventDefault() | ||
| handleInterrupt() |
There was a problem hiding this comment.
Ignore Escape from nested dialogs before interrupting session
This handler interrupts any running session for every bubbled Escape keydown inside the pane, including when the user is trying to dismiss the settings popover or close a select/menu. AgentChatSettings already binds Escape-to-close behavior, but the container onKeyDown runs earlier in the bubble path, so pressing Escape while settings are open will now also send sdk.interrupt and stop generation unexpectedly. Please scope this shortcut to contexts where Escape is intended to mean “interrupt” (e.g., composer/message area) or explicitly skip dialog/form controls.
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ailures Root cause: Freshell runs as a production server (NODE_ENV=production). When tests are invoked from within Freshell, Vitest inherits this env var. React's index.js checks process.env.NODE_ENV at runtime — when it's 'production', it loads react.production.min.js which disables act(), breaking all component tests (1048 failures). Additionally, NODE_ENV=production causes npm install to skip devDependencies in worktrees, leading to dual React instances (worktree has react but not vitest/react-dom, which fall through to main repo's node_modules). Fix: Override process.env.NODE_ENV from 'production' to 'test' at the top of both vitest config files, before any imports resolve. This ensures React loads its development build and npm install includes devDependencies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
<textarea>onKeyDowninChatComposerup to a container-levelonKeyDownon theAgentChatViewwrapper<div>withtabIndex={-1}ChatComposerto avoid double-firing; Stop button still works viaonInterruptpropTest plan
AgentChatView-interrupt.test.tsxverify container-level Escape sendssdk.interruptwhen running, does not fire when idle, and ignores non-Escape keysChatComposer.test.tsx(7 tests remain, including Stop button click)act()environment issue)🤖 Generated with Claude Code