feat: add config-backed ask keymaps
This commit is contained in:
+3
-1
@@ -4,13 +4,15 @@ This folder keeps only the documentation needed to understand and maintain the e
|
||||
|
||||
## Files
|
||||
|
||||
- `configuration.md` — source of truth for configuring pi-ask keymaps and behaviour
|
||||
- `contract.md` — external behavior, full tool payload/result details, and UX guarantees
|
||||
- `architecture.md` — module boundaries and invariants
|
||||
- `../skills/ask-user/SKILL.md` — auto-bundled agent-side decision-gate guidance; enabled by default, but can be disabled via `pi config`; inspired by https://github.com/edlsh/pi-ask-user
|
||||
|
||||
## Reading order
|
||||
|
||||
- start with `contract.md` for behavior
|
||||
- start with `configuration.md` for config-editing rules
|
||||
- read `contract.md` for behavior
|
||||
- read `architecture.md` for code layout
|
||||
|
||||
## Local test run
|
||||
|
||||
+16
-3
@@ -28,11 +28,20 @@ The codebase is split so the implementation reads through file boundaries and na
|
||||
- `src/state/view.ts` — view-mode helpers
|
||||
- `src/state.ts` — state barrel used by UI and tests
|
||||
|
||||
### Config
|
||||
|
||||
- `src/config/defaults.ts` — canonical runtime defaults
|
||||
- `src/config/schema.ts` — persisted config schema and runtime type
|
||||
- `src/config/migrate.ts` — persisted-file validation/migration boundary, including keymap normalization/fallback
|
||||
- `src/config/store.ts` — load/save/backup/runtime subscription store
|
||||
|
||||
### UI
|
||||
|
||||
- `src/ui/controller.ts` — connects key input, editor lifecycle, and pure state transitions
|
||||
- `src/ui/input.ts` — raw input to commands
|
||||
- `src/ui/render.ts` and `src/ui/render-*.ts` — screen rendering
|
||||
- `src/ui/controller.ts` — connects key input, editor lifecycle, live config subscription, and pure state transitions
|
||||
- `src/ui/input.ts` — raw input to commands using resolved config-backed keymaps
|
||||
- `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
|
||||
- `src/ui/constants.ts` and `src/ui/render-types.ts` — rendering constants/contracts
|
||||
- `src/ask-component.ts` — thin custom UI export
|
||||
|
||||
@@ -59,6 +68,10 @@ The codebase is split so the implementation reads through file boundaries and na
|
||||
- deselected option notes stay in UI state
|
||||
- only selected option notes are emitted in the final result
|
||||
- editor lifecycle stays in the controller, not in the reducers
|
||||
- persisted ask settings are versioned and normalized before use
|
||||
- invalid persisted keymaps fall back to default keymaps for the current session without discarding valid behaviour settings
|
||||
- settings modal edits a local draft and only persists on explicit save
|
||||
- live config updates can affect an in-progress ask flow immediately
|
||||
|
||||
## Documentation rule
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
# pi-ask configuration
|
||||
|
||||
This file is the source of truth for configuring `@eko24ive/pi-ask`.
|
||||
|
||||
When changing pi-ask settings:
|
||||
|
||||
1. Edit the config file.
|
||||
2. Validate keymaps against the rules below.
|
||||
3. Run `/reload` or restart pi so the new config is picked up.
|
||||
|
||||
## Config file path
|
||||
|
||||
Default path:
|
||||
|
||||
`~/.pi/agent/extensions/eko24ive-pi-ask.json`
|
||||
|
||||
## Config shape
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"behaviour": {
|
||||
"autoSubmitWhenAnsweredWithoutNotes": false
|
||||
},
|
||||
"keymaps": {
|
||||
"cancel": "esc",
|
||||
"dismiss": "ctrl+c",
|
||||
"toggle": "space",
|
||||
"confirm": "enter",
|
||||
"optionNote": "n",
|
||||
"questionNote": "shift+n"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Behaviour
|
||||
|
||||
### `behaviour.autoSubmitWhenAnsweredWithoutNotes`
|
||||
|
||||
- type: boolean
|
||||
- default: `false`
|
||||
- effect: when enabled, a fully answered ask flow with no notes can auto-submit from the review tab
|
||||
|
||||
## Keymaps
|
||||
|
||||
`keymaps` must contain all 6 configurable actions if present.
|
||||
|
||||
### Configurable actions
|
||||
|
||||
- `cancel`
|
||||
- `dismiss`
|
||||
- `toggle`
|
||||
- `confirm`
|
||||
- `optionNote`
|
||||
- `questionNote`
|
||||
|
||||
### Defaults
|
||||
|
||||
- `cancel: "esc"`
|
||||
- `dismiss: "ctrl+c"`
|
||||
- `toggle: "space"`
|
||||
- `confirm: "enter"`
|
||||
- `optionNote: "n"`
|
||||
- `questionNote: "shift+n"`
|
||||
|
||||
### Allowed bindings
|
||||
|
||||
Each configurable action accepts any single `pi-tui` key id string, as long as it is:
|
||||
|
||||
- supported by `pi-tui`
|
||||
- not reserved
|
||||
- not duplicated across configurable actions
|
||||
|
||||
Examples of valid bindings:
|
||||
|
||||
- `esc`
|
||||
- `ctrl+c`
|
||||
- `space`
|
||||
- `enter`
|
||||
- `n`
|
||||
- `shift+n`
|
||||
- `alt+f7`
|
||||
- `ctrl+[`
|
||||
- `ctrl+shift+p`
|
||||
- `super+k`
|
||||
|
||||
### Accepted alias normalization
|
||||
|
||||
Common aliases are normalized to canonical `pi-tui`-style strings.
|
||||
|
||||
Examples:
|
||||
|
||||
- `escape` -> `esc`
|
||||
- `return` -> `enter`
|
||||
- `control+c` -> `ctrl+c`
|
||||
- `Shift+N` -> `shift+n`
|
||||
- `pageup` -> `pageUp`
|
||||
- `pagedown` -> `pageDown`
|
||||
|
||||
### Reserved bindings
|
||||
|
||||
These bindings are fixed and cannot be used by configurable actions:
|
||||
|
||||
- `?`
|
||||
- `tab`
|
||||
- `shift+tab`
|
||||
- `left`
|
||||
- `right`
|
||||
- `up`
|
||||
- `down`
|
||||
- `1`
|
||||
- `2`
|
||||
- `3`
|
||||
- `4`
|
||||
- `5`
|
||||
- `6`
|
||||
- `7`
|
||||
- `8`
|
||||
- `9`
|
||||
|
||||
### Fixed bindings
|
||||
|
||||
These are intentionally not configurable:
|
||||
|
||||
- `?` opens ask settings
|
||||
- `tab`, `shift+tab`, `left`, `right` move between tabs
|
||||
- `up`, `down` move between options/actions
|
||||
- `1..9` triggers option/review shortcuts
|
||||
- `@` remains file-reference affordance in editors
|
||||
|
||||
## Invalid keymaps behavior
|
||||
|
||||
If configured keymaps are invalid:
|
||||
|
||||
- valid `behaviour` settings still load
|
||||
- invalid `keymaps` fall back to default keymaps for the current session
|
||||
- ask remains usable
|
||||
- a warning notice is shown
|
||||
- after fixing the file, run `/reload` or restart pi
|
||||
|
||||
Invalid keymaps include:
|
||||
|
||||
- missing one of the 6 required actions
|
||||
- unsupported key syntax
|
||||
- duplicate bindings across configurable actions
|
||||
- use of reserved bindings
|
||||
|
||||
## Example custom config
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"behaviour": {
|
||||
"autoSubmitWhenAnsweredWithoutNotes": true
|
||||
},
|
||||
"keymaps": {
|
||||
"cancel": "q",
|
||||
"dismiss": "ctrl+c",
|
||||
"toggle": "ctrl+t",
|
||||
"confirm": "ctrl+k",
|
||||
"optionNote": "x",
|
||||
"questionNote": "shift+x"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Agent editing rule
|
||||
|
||||
When editing this config for a user:
|
||||
|
||||
- preserve unrelated fields
|
||||
- keep `schemaVersion` at `1`
|
||||
- do not assign reserved bindings to configurable actions
|
||||
- do not create duplicate configurable bindings
|
||||
- after changing the file, tell the user to run `/reload` or restart pi
|
||||
+16
-13
@@ -199,8 +199,12 @@ This document defines the stable external behavior. It does not explain internal
|
||||
- on the review tab, `Submit` and `Cancel` preview notes only for answered questions
|
||||
- on the review tab, `Elaborate` preview expands to all question notes and all option notes, including notes on unselected options
|
||||
- transcript-friendly call and result rendering
|
||||
- ask settings modal with `Keymaps` and `Behaviour` tabs; `Behaviour` may be empty while unimplemented
|
||||
- `/ask-settings` opens the same ask settings modal as `?`
|
||||
- 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
|
||||
- `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
|
||||
- elaborate results are phrased as direct follow-up instructions, for example: `User asked to elaborate on question "Which option would you like to select?" option "Option A" with note "why this one?"`
|
||||
|
||||
## Keyboard behavior
|
||||
@@ -208,25 +212,22 @@ This document defines the stable external behavior. It does not explain internal
|
||||
Main flow:
|
||||
|
||||
- `?`: open the ask settings modal on the `Keymaps` tab
|
||||
- inside the ask settings modal, `Esc`, `Ctrl+C`, and `?` close it; dirty drafts require a second close action within a short window to discard unsaved changes
|
||||
- `Tab`, `Shift+Tab`, `Left`, `Right`: move between tabs
|
||||
- `Up`, `Down`: move between options
|
||||
- `Enter`: confirm or submit
|
||||
- `Esc`: cancel the flow
|
||||
- `Ctrl+C`: dismiss the entire flow immediately, even while editing a note or free-form answer
|
||||
- `1..9`: select or toggle the matching option; on the review tab, `1`, `2`, and `3` trigger `Submit`, `Elaborate`, and `Cancel`
|
||||
- `Space`: toggle the active option
|
||||
- `n`: edit the active option note
|
||||
- `Shift+N`: edit the current question note
|
||||
- the following actions are configurable via persisted `keymaps`: `Enter` by default confirms or submits, `Esc` cancels, `Ctrl+C` dismisses, `Space` toggles, `n` edits the active option note, and `Shift+N` edits the current question note
|
||||
|
||||
Editing flow:
|
||||
|
||||
- `Enter`: submit the current editor input and close the editor; in note editors this saves the note only and keeps the ask flow open
|
||||
- `Esc`: save draft and close the editor
|
||||
- `Ctrl+C`: dismiss the entire flow immediately without saving the current editor draft
|
||||
- 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
|
||||
- `?`: 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
|
||||
- when editor is empty, `Up`/`Down` move options and `Tab`/`Shift+Tab`/`Left`/`Right` move between tabs without requiring `Esc` first
|
||||
- navigation resumes only after closing the editor with `Esc`, unless the editor is empty and the navigation keys above are used
|
||||
- when editor is empty, `Up`/`Down` move options and `Tab`/`Shift+Tab`/`Left`/`Right` move between tabs without requiring the configurable cancel key first
|
||||
- navigation resumes only after closing the editor with the configurable `cancel` binding, unless the editor is empty and the navigation keys above are used
|
||||
|
||||
## Non-interactive mode
|
||||
|
||||
@@ -234,6 +235,8 @@ 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 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.
|
||||
|
||||
## Skill alignment (advisory)
|
||||
|
||||
Reference in New Issue
Block a user