https://github.com/monotykamary/pi-double-esc
Prevent accidental Escape from aborting the LLM — requires double-press to interrupt while streaming
https://github.com/monotykamary/pi-double-esc
debounce double-escape escape extension interrupt pi pi-coding-agent pi-package
Last synced: about 14 hours ago
JSON representation
Prevent accidental Escape from aborting the LLM — requires double-press to interrupt while streaming
- Host: GitHub
- URL: https://github.com/monotykamary/pi-double-esc
- Owner: monotykamary
- Created: 2026-05-07T13:21:03.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-21T12:17:11.000Z (6 days ago)
- Last Synced: 2026-06-21T14:33:28.385Z (6 days ago)
- Topics: debounce, double-escape, escape, extension, interrupt, pi, pi-coding-agent, pi-package
- Language: TypeScript
- Homepage: https://github.com/monotykamary/pi-double-esc#readme
- Size: 164 KB
- Stars: 4
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
Awesome Lists containing this project
- awesome-pi-coding-agent - monotykamary-pi-double-esc - press to interrupt while streaming | ⭐4 | 8d ago | (Miscellaneous)
README
# ⏏️ pi-double-esc
**Prevent accidental Escape aborts in [pi](https://github.com/earendil-works/pi-coding-agent)**
_Require a second Escape press within 500ms to confirm any abort action._
[](https://github.com/earendil-works/pi-coding-agent)
[](./LICENSE)

---
## What It Does
When the LLM is streaming a response:
- **First Escape press**: Shows an `esc again to abort` hint on the editor border — does **not** abort
- **Second Escape** within the debounce window: Actually aborts the streaming response
- If the debounce window expires, the hint clears and escape resets
When the LLM is **not** streaming, Escape works normally (immediate) — no debounce applied. Autocomplete dismissal always works on a single Escape.
## Installation
### Option 1: Install via pi package (Recommended)
Install directly from GitHub as a pi package:
```bash
pi install https://github.com/monotykamary/pi-double-esc@main
```
Or add to your `settings.json`:
```json
{
"packages": [
"https://github.com/monotykamary/pi-double-esc@main"
]
}
```
### Option 2: Global Installation
Copy the extension to pi's global extensions directory:
```bash
cp double-esc.ts ~/.pi/agent/extensions/
```
### Option 3: Project-Local Installation
Copy to your project's `.pi/extensions/` directory:
```bash
mkdir -p .pi/extensions
cp double-esc.ts .pi/extensions/
```
### Option 4: Quick Test
```bash
pi -e ./double-esc.ts
```
## Configuration
Set the `PI_DOUBLE_ESC_MS` environment variable to change the debounce timeout (default: 1500ms):
```bash
PI_DOUBLE_ESC_MS=2000 pi
```
## How It Works
The extension replaces pi's editor component with a `CustomEditor` subclass that intercepts Escape key presses:
1. On each `session_start`, `ctx.ui.setEditorComponent()` installs the custom editor
2. The editor uses `ctx.isIdle()` (which reflects `!session.isStreaming`) to detect streaming state
3. While streaming, the first Escape shows a visual hint and starts a debounce timer
4. A second Escape within the window calls `super.handleInput(data)` to perform the actual abort
5. Any other keypress or timeout expiry dismisses the hint
The debounce logic lives in `src/double-esc-logic.ts` as pure functions for testability.
## Development
```bash
npm install # install dev dependencies
npm test # run tests
npm run typecheck # type check
npm run lint:dead # check for unused exports
```
## License
MIT