Skip to content

feat(cli): support Ctrl-Z suspension#18931

Merged
scidomino merged 1 commit intomainfrom
agentic-utils/main
Feb 12, 2026
Merged

feat(cli): support Ctrl-Z suspension#18931
scidomino merged 1 commit intomainfrom
agentic-utils/main

Conversation

@scidomino
Copy link
Collaborator

@scidomino scidomino commented Feb 12, 2026

Summary

  • Restores Ctrl+Z functionality to suspend the CLI process.
  • Resolves keybinding conflicts and refines suspend behavior.

Details

This is a local version of #17630 with merge conflicts resolved. I don't have write access to the fork so I have to create another branch to merge these on.

Related Issues

Fixes #5018

How to Validate

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@scidomino scidomino marked this pull request as ready for review February 12, 2026 17:41
@scidomino scidomino requested review from a team as code owners February 12, 2026 17:41
@github-actions
Copy link

Size Change: +3.83 kB (+0.02%)

Total Size: 24.3 MB

Filename Size Change
./bundle/gemini.js 24.3 MB +3.83 kB (+0.02%)
ℹ️ View Unchanged
Filename Size
./bundle/sandbox-macos-permissive-closed.sb 1.03 kB
./bundle/sandbox-macos-permissive-open.sb 890 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-closed.sb 3.29 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB

compressed-size-action

Copy link
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @scidomino, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces robust support for suspending the CLI application using the Ctrl+Z key combination. It addresses previous limitations by implementing a dedicated React hook to manage the intricate terminal state changes required for proper suspension and resumption. The changes ensure a consistent and functional experience across supported platforms, with appropriate warnings for unsupported environments like Windows.

Highlights

  • Ctrl+Z Suspension Implemented: The CLI now supports suspending the application using Ctrl+Z, moving it to the background, and resuming it later. This resolves a long-standing feature request.
  • New useSuspend Hook: A dedicated React hook, useSuspend, was introduced to encapsulate the complex logic for handling terminal state (raw mode, alternate screen buffer, mouse events) during suspension and resumption.
  • Refined Terminal State Management: The terminal's raw mode, alternate screen buffer, line wrapping, and mouse event settings are now properly saved before suspension and restored upon resumption, ensuring a seamless user experience.
  • Keybinding Conflict Resolution: The previous placeholder warning for Ctrl+Z (which suggested 'Undo' had moved) has been removed, and Ctrl+Z is now correctly mapped to the suspend action.
  • Windows Platform Handling: The suspension functionality gracefully handles the Windows platform by issuing a warning that Ctrl+Z suspend is not supported, preventing unexpected behavior.
  • Documentation and Test Coverage: The keyboard shortcuts documentation and keybinding descriptions have been updated, and comprehensive unit tests for the new useSuspend hook and Ctrl+Z key matcher have been added.
Changelog
  • docs/cli/keyboard-shortcuts.md
    • Updated the description for the Ctrl + Z shortcut to reflect its new suspend functionality.
  • packages/cli/src/config/keyBindings.ts
    • Modified the description for Command.SUSPEND_APP to indicate that it now suspends the CLI.
  • packages/cli/src/ui/AppContainer.test.tsx
    • Mocked and imported the new useSuspend hook for testing purposes.
    • Refactored configuration mocking to use makeFakeConfig() and vi.spyOn for better test isolation.
    • Added a new test suite to verify that handleSuspend is called when Ctrl+Z is pressed.
  • packages/cli/src/ui/AppContainer.tsx
    • Imported additional ink components (useApp, useStdout, useStdin, AppProps) and the new useSuspend hook.
    • Introduced a forceRerenderKey state to facilitate component remounting after suspension/resumption.
    • Integrated the useSuspend hook, passing necessary callbacks and state for terminal management.
    • Mapped the Command.SUSPEND_APP key matcher to call the handleSuspend function.
    • Removed the old warning message logic previously associated with Command.SUSPEND_APP.
    • Updated the App component to use a key prop, enabling forced remounts.
  • packages/cli/src/ui/components/snapshots/InputPrompt.test.tsx.snap
    • Updated snapshots to reflect minor rendering changes, likely due to refactoring in AppContainer.tsx.
  • packages/cli/src/ui/hooks/useSuspend.test.ts
    • Added a new test file for the useSuspend hook.
    • Implemented tests covering terminal state cleanup and restoration on suspend/resume in alternate screen mode.
    • Included tests to verify correct behavior when alternate screen mode is disabled.
    • Added a test case to confirm that suspension is not supported and a warning is issued on Windows.
  • packages/cli/src/ui/hooks/useSuspend.ts
    • Added a new React hook, useSuspend, to manage the Ctrl+Z suspension and resumption lifecycle.
    • Implemented logic to save and restore terminal raw mode, alternate screen buffer, line wrapping, and mouse events.
    • Included a mechanism to warn users on the first Ctrl+Z press and perform suspension on the second.
    • Added platform-specific handling to disable suspension on Windows.
  • packages/cli/src/ui/keyMatchers.test.ts
    • Added new test cases to validate the key matching for Command.SUSPEND_APP (Ctrl+Z).
  • packages/cli/src/ui/utils/terminalCapabilityManager.ts
    • Extracted terminal cleanup sequences into a new cleanupTerminalOnExit function.
    • Updated TerminalCapabilityManager to utilize the new cleanupTerminalOnExit function for event listeners, centralizing terminal cleanup logic.
Activity
  • The pull request author, scidomino, implemented Ctrl+Z suspension functionality.
  • The author resolved merge conflicts from an upstream pull request (feat(cli): support Ctrl-Z suspension #17630) to integrate this feature.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@scidomino scidomino enabled auto-merge February 12, 2026 17:55
@scidomino scidomino added this pull request to the merge queue Feb 12, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for suspending the CLI process using Ctrl+Z. The implementation introduces a new useSuspend hook to encapsulate the logic for cleaning up and restoring the terminal state, and adds corresponding tests. The documentation and keybinding descriptions are also updated.

My review found one critical issue: the new keybinding for SUSPEND_APP conflicts with the existing REDO command (Ctrl+Shift+Z), which would break the redo functionality. I've provided a detailed comment and suggestion in packages/cli/src/ui/keyMatchers.test.ts to resolve this conflict by making the keybinding more specific and updating the related test case.

The rest of the changes, including the suspend/resume logic and test refactoring, look solid.

Comment on lines +334 to +343
command: Command.SUSPEND_APP,
positive: [
createKey('z', { ctrl: true }),
createKey('z', { ctrl: true, shift: true }),
],
negative: [
createKey('z'),
createKey('y', { ctrl: true }),
createKey('z', { alt: true }),
],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This test case incorrectly asserts that Ctrl+Shift+Z is a valid keybinding for SUSPEND_APP. This introduces a critical bug by creating a keybinding conflict with the REDO command, which is also bound to Ctrl+Shift+Z.

The current binding for SUSPEND_APP in packages/cli/src/config/keyBindings.ts is { key: 'z', ctrl: true }. Since shift is not specified, it matches both Ctrl+Z and Ctrl+Shift+Z. Because the global keypress handler has higher priority, it will intercept Ctrl+Shift+Z and trigger a suspend, breaking the "redo" functionality.

To fix this, two changes are needed:

  1. Update the keybinding definition in packages/cli/src/config/keyBindings.ts on line 298 to be more specific:

    [Command.SUSPEND_APP]: [{ key: 'z', ctrl: true, shift: false }],

    (Since this file is not fully in the diff, I'm adding this context here).

  2. Update this test case to correctly assert that Ctrl+Shift+Z is a negative case for SUSPEND_APP.

Here is the suggested change for this test file:

Suggested change
command: Command.SUSPEND_APP,
positive: [
createKey('z', { ctrl: true }),
createKey('z', { ctrl: true, shift: true }),
],
negative: [
createKey('z'),
createKey('y', { ctrl: true }),
createKey('z', { alt: true }),
],
command: Command.SUSPEND_APP,
positive: [
createKey('z', { ctrl: true }),
],
negative: [
createKey('z', { ctrl: true, shift: true }),
createKey('z'),
createKey('y', { ctrl: true }),
createKey('z', { alt: true }),
],

Merged via the queue into main with commit 375ebca Feb 12, 2026
30 of 31 checks passed
@scidomino scidomino deleted the agentic-utils/main branch February 12, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Ctrl-Z suspension

3 participants