feat: add dirty-dismiss and footer hint settings

This commit is contained in:
Erik Kotsiuba
2026-04-28 22:35:43 +02:00
parent 85962d985d
commit 18120e8801
17 changed files with 373 additions and 24 deletions
+2 -1
View File
@@ -37,8 +37,9 @@ The codebase is split so the implementation reads through file boundaries and na
### UI
- `src/ui/controller.ts` — connects key input, editor lifecycle, live config subscription, and pure state transitions
- `src/ui/controller.ts` — connects key input, editor lifecycle, live config subscription, dirty-dismiss confirmation, and pure state transitions
- `src/ui/input.ts` — raw input to commands using resolved config-backed keymaps
- `src/ui/dismiss-guard.ts` — pure helpers for dirty-flow exit confirmation behavior
- `src/ui/render.ts` and `src/ui/render-*.ts` — screen rendering, including config-backed footer/keymap hints
- `src/ui/settings-state.ts` — pure settings-modal draft/dirty/notice state
- `src/ui/settings-modal.ts` / `src/ui/show-settings-modal.ts` — ask settings modal rendering and launcher
+20 -2
View File
@@ -20,7 +20,9 @@ Default path:
{
"schemaVersion": 1,
"behaviour": {
"autoSubmitWhenAnsweredWithoutNotes": false
"autoSubmitWhenAnsweredWithoutNotes": false,
"confirmDismissWhenDirty": false,
"showFooterHints": true
},
"keymaps": {
"cancel": "esc",
@@ -41,6 +43,20 @@ Default path:
- default: `false`
- effect: when enabled, a fully answered ask flow with no notes can auto-submit from the review tab
### `behaviour.confirmDismissWhenDirty`
- type: boolean
- default: `false`
- effect: when enabled, discarding a dirty ask flow requires a second cancel/dismiss action
- the warning stays visible until the user changes tabs in the ask flow
- dirty means there are saved answers/notes or unsaved editor draft text
### `behaviour.showFooterHints`
- type: boolean
- default: `true`
- effect: when disabled, the ask flow hides the footer keymap hints
## Keymaps
`keymaps` must contain all 6 configurable actions if present.
@@ -151,7 +167,9 @@ Invalid keymaps include:
{
"schemaVersion": 1,
"behaviour": {
"autoSubmitWhenAnsweredWithoutNotes": true
"autoSubmitWhenAnsweredWithoutNotes": true,
"confirmDismissWhenDirty": true,
"showFooterHints": false
},
"keymaps": {
"cancel": "q",
+5 -3
View File
@@ -202,7 +202,7 @@ This document defines the stable external behavior. It does not explain internal
- transcript-friendly call and result rendering
- ask settings modal with `Keymaps` and `Behaviour` tabs
- `?` in the ask flow and `/ask-settings` in pi open the same ask settings modal
- `Behaviour` exposes `Auto-submit when answered without notes` as a persisted user setting
- `Behaviour` exposes persisted user settings for `Auto-submit when answered without notes`, `Confirm dismiss when dirty`, and `Show footer hints`
- `Keymaps` is a persisted config section for `cancel`, `dismiss`, `toggle`, `confirm`, `optionNote`, and `questionNote`
- the `Keymaps` tab is read-only and shows the active bindings plus the config file path
- if the flow is already on the review tab, all questions are answered, and no notes exist, enabling auto-submit can complete the current ask flow immediately
@@ -223,7 +223,9 @@ Editing flow:
- the configurable `confirm` binding submits the current editor input and closes the editor; in note editors this saves the note only and keeps the ask flow open
- the configurable `cancel` binding saves draft and closes the editor
- the configurable `dismiss` binding dismisses the entire flow immediately without saving the current editor draft
- when `Confirm dismiss when dirty` is enabled, cancelling or dismissing a dirty ask flow requires the same action a second time
- the dirty-dismiss warning stays visible until the user changes tabs in the ask flow
- the configurable `dismiss` binding dismisses the entire flow immediately without saving the current editor draft when no dirty-dismiss confirmation is pending
- `?`: open the ask settings modal on the `Keymaps` tab when the editor is empty; otherwise enter `?` as text
- inside the ask settings modal, `Ctrl+S` saves the current draft config without closing the modal
- when editor has text, arrow keys and `Tab` stay in the editor so the cursor can move while typing
@@ -236,7 +238,7 @@ If `ctx.hasUI === false`, the tool returns a `Needs user input` message in `cont
Validation is handled inside the tool so malformed calls produce the same structured error shape as other invalid payloads instead of relying on pre-execution schema failures.
The ask flow subscribes to runtime settings updates while open. In practice, this means changing `Auto-submit when answered without notes` or reloading config-backed keymaps can affect the in-progress ask flow immediately instead of only future asks.
The ask flow subscribes to runtime settings updates while open. In practice, this means changing `Auto-submit when answered without notes`, `Confirm dismiss when dirty`, `Show footer hints`, or reloading config-backed keymaps can affect the in-progress ask flow immediately instead of only future asks.
The fallback message includes normalized pending questions and options so the caller can re-ask them manually. `details.questions` still contains normalized question metadata, while `details.answers` stays empty until a user responds.