Make ESC handling clearer and more maintainable by extracting ESC logic into a dedicated, independent module under src/tunacode/ui/esc/. The ESC node (handler) should be independent of app internals and depend only on explicit inputs passed in.
Non-goals:
No behavior changes to ESC handling
No UI changes or visual redesigns
No new features beyond structural refactor
Scope & Assumptions
In scope:
Introduce src/tunacode/ui/esc/ directory
Extract app-level ESC cascade logic into a standalone component
1---2name: 504-2026-02-02-13-29-36-esc-logic-module-extraction-c750cf353description: Goal4---56## Goal78Make ESC handling clearer and more maintainable by extracting ESC logic into a dedicated, independent module under `src/tunacode/ui/esc/`. The ESC node (handler) should be independent of app internals and depend only on explicit inputs passed in.910**Non-goals:**11- No behavior changes to ESC handling12- No UI changes or visual redesigns13- No new features beyond structural refactor1415## Scope & Assumptions1617**In scope:**18- Introduce `src/tunacode/ui/esc/` directory19- Extract app-level ESC cascade logic into a standalone component20- Define a minimal, explicit dependency interface (request cancel, shell cancel, editor clear)21- Preserve modal-level ESC behavior (two-phase picker logic, dismiss semantics)2223**Out of scope:**24- Changing modal screen behavior25- Adding new key bindings26- Refactoring unrelated UI components2728**Assumptions:**29- Existing ESC behavior is correct and should be preserved30- App-level ESC flow can be encapsulated without breaking Textual binding semantics3132## Deliverables (DoD)33341. ESC logic lives in `src/tunacode/ui/esc/` with clear public API352. App ESC binding delegates to the new ESC handler363. Modal screen ESC logic remains unchanged and documented374. No new mypy errors385. Ruff clean (`uv run ruff check .`)3940## Readiness (DoR)4142- [x] Research doc complete (ESC flow mapping)43- [x] Target files identified44- [ ] Proposed module interface reviewed4546## Proposed Module Design4748- **Module path:** `src/tunacode/ui/esc/`49- **Primary entry:** `EscHandler` (or similar) with a single `handle_escape(...)` method50- **Dependencies passed explicitly:**51 - `current_request_task` (or a cancel callable)52 - `shell_runner` (or a cancel callable + is_running)53 - `editor` (or a clear callable + has_content/has_paste_buffer)54- **No hidden state:** all state required for decisions is passed in or queried via explicit interfaces55- **App integration:** `TunaApp.action_cancel_request()` delegates to `EscHandler` and performs no logic itself5657## Work Breakdown (Tasks)5859| Task | ID | Summary | File(s) | Notes |60|------|-----|---------|---------|-------|61| T1 | tk-new | Define `ui/esc` package + handler API | `src/tunacode/ui/esc/__init__.py` | Public interface only |62| T2 | tk-new | Move app-level ESC cascade into handler | `src/tunacode/ui/app.py`, `src/tunacode/ui/esc/handler.py` | Preserve cascade order |63| T3 | tk-new | Add minimal protocol/typing for dependencies | `src/tunacode/ui/esc/types.py` | Explicit inputs only |64| T4 | tk-new | Update docs/comments to reflect new location | `src/tunacode/ui/app.py` | Avoid behavior changes |6566## Risks & Mitigations6768| Risk | Impact | Likelihood | Mitigation | Trigger |69|------|--------|------------|------------|---------|70| Binding priority behavior changes | High | Low | Keep `priority=True` binding in app; delegate only | ESC fails to cancel as before |71| Dependency coupling creeps back | Medium | Medium | Enforce explicit inputs in handler API | Handler starts importing app state |72| Behavior drift in cascade order | High | Low | Mirror exact order and early returns | ESC clears input when request running |7374## Test Strategy7576- **No new tests** (behavioral equivalence)77- Manual sanity checks:78 - ESC cancels request task first79 - ESC cancels shell next80 - ESC clears editor only when nothing else active81 - Modal ESC behavior unchanged82- Run: `uv run pytest` (if required by workflow)8384## References8586- Research doc: `memory-bank/research/2026-02-02_12-56-40_esc-key-flow.md`87- Current ESC logic: `src/tunacode/ui/app.py` (binding + cascade)88- Modal ESC logic: `src/tunacode/ui/screens/*.py`89- Editor clear logic: `src/tunacode/ui/widgets/editor.py`90- Shell cancel logic: `src/tunacode/ui/shell_runner.py`
Run npx skillmds@latest add tools-only/504-2026-02-02-13-29-36-esc-logic-module-extraction-c750cf35 in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Goal It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
tools-only (@tools-only) published this skill. Their other Agent Skills are listed on their SkillMD profile.