{"id":50234701,"url":"https://github.com/monotykamary/pi-double-esc","last_synced_at":"2026-06-26T20:02:46.239Z","repository":{"id":356315689,"uuid":"1231977031","full_name":"monotykamary/pi-double-esc","owner":"monotykamary","description":"Prevent accidental Escape from aborting the LLM — requires double-press to interrupt while streaming","archived":false,"fork":false,"pushed_at":"2026-06-21T12:17:11.000Z","size":168,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-21T14:33:28.385Z","etag":null,"topics":["debounce","double-escape","escape","extension","interrupt","pi","pi-coding-agent","pi-package"],"latest_commit_sha":null,"homepage":"https://github.com/monotykamary/pi-double-esc#readme","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monotykamary.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"monotykamary","ko_fi":"monotykamary","buy_me_a_coffee":"monotykamary","polar":"monotykamary"}},"created_at":"2026-05-07T13:21:03.000Z","updated_at":"2026-06-21T12:17:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/monotykamary/pi-double-esc","commit_stats":null,"previous_names":["monotykamary/pi-double-esc"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/monotykamary/pi-double-esc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monotykamary%2Fpi-double-esc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monotykamary%2Fpi-double-esc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monotykamary%2Fpi-double-esc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monotykamary%2Fpi-double-esc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monotykamary","download_url":"https://codeload.github.com/monotykamary/pi-double-esc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monotykamary%2Fpi-double-esc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34831250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debounce","double-escape","escape","extension","interrupt","pi","pi-coding-agent","pi-package"],"created_at":"2026-05-26T19:00:32.278Z","updated_at":"2026-06-26T20:02:46.235Z","avatar_url":"https://github.com/monotykamary.png","language":"TypeScript","funding_links":["https://github.com/sponsors/monotykamary","https://ko-fi.com/monotykamary","https://buymeacoffee.com/monotykamary","https://polar.sh/monotykamary"],"categories":["Miscellaneous"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# ⏏️ pi-double-esc\n\n**Prevent accidental Escape aborts in [pi](https://github.com/earendil-works/pi-coding-agent)**\n\n_Require a second Escape press within 500ms to confirm any abort action._\n\n[![pi extension](https://img.shields.io/badge/pi-extension-blueviolet)](https://github.com/earendil-works/pi-coding-agent)\n[![license](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)\n\n\u003cimg alt=\"double-esc hint\" src=\"./media/esc.jpg\" width=\"800\"\u003e\n\n\u003c/div\u003e\n\n---\n\n## What It Does\n\nWhen the LLM is streaming a response:\n\n- **First Escape press**: Shows an `esc again to abort` hint on the editor border — does **not** abort\n- **Second Escape** within the debounce window: Actually aborts the streaming response\n- If the debounce window expires, the hint clears and escape resets\n\nWhen the LLM is **not** streaming, Escape works normally (immediate) — no debounce applied. Autocomplete dismissal always works on a single Escape.\n\n## Installation\n\n### Option 1: Install via pi package (Recommended)\n\nInstall directly from GitHub as a pi package:\n\n```bash\npi install https://github.com/monotykamary/pi-double-esc@main\n```\n\nOr add to your `settings.json`:\n\n```json\n{\n  \"packages\": [\n    \"https://github.com/monotykamary/pi-double-esc@main\"\n  ]\n}\n```\n\n### Option 2: Global Installation\n\nCopy the extension to pi's global extensions directory:\n\n```bash\ncp double-esc.ts ~/.pi/agent/extensions/\n```\n\n### Option 3: Project-Local Installation\n\nCopy to your project's `.pi/extensions/` directory:\n\n```bash\nmkdir -p .pi/extensions\ncp double-esc.ts .pi/extensions/\n```\n\n### Option 4: Quick Test\n\n```bash\npi -e ./double-esc.ts\n```\n\n## Configuration\n\nSet the `PI_DOUBLE_ESC_MS` environment variable to change the debounce timeout (default: 1500ms):\n\n```bash\nPI_DOUBLE_ESC_MS=2000 pi\n```\n\n## How It Works\n\nThe extension replaces pi's editor component with a `CustomEditor` subclass that intercepts Escape key presses:\n\n1. On each `session_start`, `ctx.ui.setEditorComponent()` installs the custom editor\n2. The editor uses `ctx.isIdle()` (which reflects `!session.isStreaming`) to detect streaming state\n3. While streaming, the first Escape shows a visual hint and starts a debounce timer\n4. A second Escape within the window calls `super.handleInput(data)` to perform the actual abort\n5. Any other keypress or timeout expiry dismisses the hint\n\nThe debounce logic lives in `src/double-esc-logic.ts` as pure functions for testability.\n\n## Development\n\n```bash\nnpm install          # install dev dependencies\nnpm test            # run tests\nnpm run typecheck   # type check\nnpm run lint:dead   # check for unused exports\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonotykamary%2Fpi-double-esc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonotykamary%2Fpi-double-esc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonotykamary%2Fpi-double-esc/lists"}