fix: enable cancellation of slash commands and background processes
Summary
Enables proper cancellation when users press Escape during slash command execution, including termination of background processes spawned by shell commands. Addresses issue #6066 where slash commands did not respect the top-level cancellation signal.
Key Changes
- AbortSignal propagation: Added signal parameter to slash command processor chain
-
Background process termination: Implemented
killAllBackgroundProcesses()with cross-platform support - Global PID tracking: Added tracking for background processes across async boundaries
- Signal integration: Connected cancellation hooks throughout command execution flow
- Comprehensive tests: Added test coverage for new functionality
Technical Implementation
Core Cancellation Flow
- User presses Escape →
useGeminiStream.cancelOngoingRequest() - Calls
killAllBackgroundProcesses()to terminate spawned processes - AbortSignal propagates through
handleSlashCommand→createCommandContext - Commands receive signal and can respond to cancellation appropriately
Background Process Management
- Cross-platform termination: Uses process groups (SIGTERM/SIGKILL) on Unix, taskkill on Windows
- Global PID tracking: Maintains Set of background PIDs for cleanup on cancellation
- Graceful shutdown: SIGTERM followed by SIGKILL after timeout
Code Quality Improvements
- Refactored to useCallback: Addressed memoization code smell from PR feedback
- Signal parameter pattern: Changed from creating dummy signals to accepting signal as parameter
- App-level AbortController: Added for programmatic command lifecycle management
Test Coverage
- ✅ Background process termination: Tests Unix/Windows process killing, error handling, PID tracking
- ✅ Integration tests: Verifies cancellation flow in
useGeminiStream - ✅ Signal propagation: Tests AbortSignal parameter passing through command chain
- ✅ Cross-platform support: Tests both Unix and Windows process termination methods
Fixes
- Background processes now properly terminate when cancellation occurs (addresses #6066)
- Shell commands like
/tmp/long_counter.sh &can be cancelled with Escape - Proper signal propagation prevents zombie processes and resource leaks
- useCallback pattern eliminates memoization code smell from previous implementation
Fixes #6066
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).
View this failed invocation of the CLA check for more information.
For the most up to date status, view the checks section at the bottom of the pull request.
@abhipatel12 pls review.
@abhipatel12 sorry about that. The fixed it now. please check.
@abhipatel12 done. Please check now.
Fixed the build it. sorry about that. PTAL @abhipatel12
created a new issue https://github.com/google-gemini/gemini-cli/issues/10978
Resolved suggested changes. PTAL @abhipatel12
Thank you for submission to the Gemini CLI project. At this time, we are closing this pull request in order to allow us to better triage and support more recent pull requests against the latest code changes. If you feel like this pull request is a critical contribution to the Gemini CLI project, please associate the pull request with an existing GitHub issue (instructions here: https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue) before reopening. After Monday January 26 2026, any pull requests submitted by contributors without an associated issue will be automatically closed (more information here: https://github.com/google-gemini/gemini-cli/discussions/16706). If you do choose to reopen and submit this pull request, please ensure you rebase your changes onto the current main branch before resubmitting. This will help avoid merge conflicts and ensure your contribution is compatible with the latest codebase.