@geoqiao/pi-ask 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +194 -0
- package/LICENSE +22 -0
- package/README.md +282 -0
- package/docs/README.md +33 -0
- package/docs/configuration.md +406 -0
- package/docs/contract.md +309 -0
- package/docs/remote-events.md +187 -0
- package/package.json +130 -0
- package/skills/ask-user/SKILL.md +110 -0
- package/src/answer-commands.ts +361 -0
- package/src/answer-extraction.ts +354 -0
- package/src/ask-payload-store.ts +86 -0
- package/src/ask-settings-command.ts +14 -0
- package/src/ask-tool-helpers.ts +172 -0
- package/src/ask-tool.ts +84 -0
- package/src/config/defaults.ts +216 -0
- package/src/config/migrate.ts +70 -0
- package/src/config/migrations/index.ts +139 -0
- package/src/config/migrations/types.ts +10 -0
- package/src/config/schema.ts +287 -0
- package/src/config/store.ts +227 -0
- package/src/constants/keymaps.ts +721 -0
- package/src/constants/text.ts +12 -0
- package/src/constants/ui.ts +22 -0
- package/src/index.ts +30 -0
- package/src/math.ts +3 -0
- package/src/notifications.ts +119 -0
- package/src/remote-ask.ts +563 -0
- package/src/result-format.ts +157 -0
- package/src/result.ts +23 -0
- package/src/schema.ts +74 -0
- package/src/state/answers.ts +251 -0
- package/src/state/create.ts +18 -0
- package/src/state/editor.ts +70 -0
- package/src/state/navigation.ts +86 -0
- package/src/state/normalize.ts +326 -0
- package/src/state/question-type.ts +128 -0
- package/src/state/result.ts +263 -0
- package/src/state/selectors.ts +135 -0
- package/src/state/transitions.ts +330 -0
- package/src/state/view.ts +28 -0
- package/src/text.ts +98 -0
- package/src/types.ts +169 -0
- package/src/ui/auto-submit.ts +36 -0
- package/src/ui/autocomplete.ts +52 -0
- package/src/ui/controller.ts +645 -0
- package/src/ui/dismiss-guard.ts +26 -0
- package/src/ui/input.ts +160 -0
- package/src/ui/render-frame.ts +235 -0
- package/src/ui/render-helpers.ts +385 -0
- package/src/ui/render-question.ts +288 -0
- package/src/ui/render-submit.ts +168 -0
- package/src/ui/render-types.ts +33 -0
- package/src/ui/render.ts +53 -0
- package/src/ui/review-shortcuts.ts +43 -0
- package/src/ui/settings-list.ts +461 -0
- package/src/ui/show-settings.ts +37 -0
- package/src/ui/view-models/question.ts +203 -0
- package/src/ui/view-models/review.ts +100 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# pi-ask configuration
|
|
2
|
+
|
|
3
|
+
This file is the source of truth for configuring `@eko24ive/pi-ask`.
|
|
4
|
+
|
|
5
|
+
When changing pi-ask settings:
|
|
6
|
+
|
|
7
|
+
1. Edit the config file.
|
|
8
|
+
2. Validate keymaps against the rules below.
|
|
9
|
+
3. Run `/reload` or restart pi so the new config is picked up.
|
|
10
|
+
|
|
11
|
+
pi-ask treats this file as user-owned config. It does not rewrite or back up the file just because it was loaded, migrated, or found invalid. Settings toggled in `/ask-settings` are saved only when the file is writable; if saving fails, pi-ask reverts the toggle and shows the config path to edit manually.
|
|
12
|
+
|
|
13
|
+
## Config file path
|
|
14
|
+
|
|
15
|
+
Default path:
|
|
16
|
+
|
|
17
|
+
`~/.pi/agent/extensions/eko24ive-pi-ask.json`
|
|
18
|
+
|
|
19
|
+
If the file does not exist yet, pi-ask attempts to create it with the current default settings the first time the ask flow is used. If the config location is read-only or managed outside pi-ask, pi-ask uses built-in defaults for the session and leaves disk unchanged.
|
|
20
|
+
|
|
21
|
+
Older pi-ask versions wrote this file at `~/.pi/agent/eko24ive-pi-ask.json`. If that legacy file exists and the extensions config does not, pi-ask reads the legacy file as a fallback and leaves disk unchanged. If both files exist, pi-ask uses the extensions config and leaves the legacy root file untouched.
|
|
22
|
+
|
|
23
|
+
## Config versions and migrations
|
|
24
|
+
|
|
25
|
+
`schemaVersion` identifies the persisted config shape. pi-ask migrates older supported schema versions forward in memory before validation. Migrations preserve existing user-provided values and add new fields from defaults when needed, but loading a config does not rewrite the file.
|
|
26
|
+
|
|
27
|
+
Unsupported future versions or invalid files are left unchanged and defaults are loaded for the current session. Fix the file, then run `/reload` or restart pi.
|
|
28
|
+
|
|
29
|
+
## Config shape
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"schemaVersion": 5,
|
|
34
|
+
"answer": {
|
|
35
|
+
"extractionModels": [
|
|
36
|
+
{ "provider": "openai-codex", "id": "<model-id>" },
|
|
37
|
+
{ "provider": "github-copilot", "id": "<model-id>" },
|
|
38
|
+
{ "provider": "anthropic", "id": "<model-id>" }
|
|
39
|
+
],
|
|
40
|
+
"extractionTimeoutMs": 30000,
|
|
41
|
+
"extractionRetries": 1
|
|
42
|
+
},
|
|
43
|
+
"behaviour": {
|
|
44
|
+
"autoSubmitWhenAnsweredWithoutNotes": false,
|
|
45
|
+
"confirmDismissWhenDirty": true,
|
|
46
|
+
"doublePressReviewShortcuts": true,
|
|
47
|
+
"presentSingleAsMulti": false,
|
|
48
|
+
"showFooterHints": true
|
|
49
|
+
},
|
|
50
|
+
"keymaps": {
|
|
51
|
+
"global": { "dismiss": ["ctrl+c"], "settings": ["?"] },
|
|
52
|
+
"main": {
|
|
53
|
+
"confirm": ["enter"],
|
|
54
|
+
"cancel": ["esc"],
|
|
55
|
+
"toggle": ["space"],
|
|
56
|
+
"changeQuestionType": ["t"],
|
|
57
|
+
"nextTab": ["tab", "right"],
|
|
58
|
+
"previousTab": ["shift+tab", "left"],
|
|
59
|
+
"nextOption": ["down"],
|
|
60
|
+
"previousOption": ["up"],
|
|
61
|
+
"optionNote": ["n"],
|
|
62
|
+
"questionNote": ["shift+n"]
|
|
63
|
+
},
|
|
64
|
+
"editor": {
|
|
65
|
+
"submit": ["enter"],
|
|
66
|
+
"close": ["esc"],
|
|
67
|
+
"nextTabWhenEmpty": ["tab", "right"],
|
|
68
|
+
"previousTabWhenEmpty": ["shift+tab", "left"],
|
|
69
|
+
"nextOptionWhenEmpty": ["down"],
|
|
70
|
+
"previousOptionWhenEmpty": ["up"]
|
|
71
|
+
},
|
|
72
|
+
"noteEditor": {
|
|
73
|
+
"save": ["enter"],
|
|
74
|
+
"close": ["esc"],
|
|
75
|
+
"nextTabWhenEmpty": ["tab", "right"],
|
|
76
|
+
"previousTabWhenEmpty": ["shift+tab", "left"],
|
|
77
|
+
"nextOptionWhenEmpty": ["down"],
|
|
78
|
+
"previousOptionWhenEmpty": ["up"]
|
|
79
|
+
},
|
|
80
|
+
"settingsModal": {
|
|
81
|
+
"close": ["esc", "ctrl+c", "?"],
|
|
82
|
+
"nextOption": ["down"],
|
|
83
|
+
"previousOption": ["up"],
|
|
84
|
+
"toggle": ["enter", "space"]
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"notifications": {
|
|
88
|
+
"enabled": true,
|
|
89
|
+
"channels": ["bell"]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Answer extraction
|
|
95
|
+
|
|
96
|
+
These settings affect only the `/answer` command. Normal `ask_user` tool calls do not use an extraction model.
|
|
97
|
+
|
|
98
|
+
### `answer.extractionModels`
|
|
99
|
+
|
|
100
|
+
- type: array of `{ "provider": string, "id": string }`
|
|
101
|
+
- default: lightweight OpenAI Codex, GitHub Copilot, and Anthropic models
|
|
102
|
+
- effect: `/answer` tries configured models in order and uses the first model with available auth
|
|
103
|
+
- fallback: if no configured model is usable, `/answer` tries the current chat model after validating its auth
|
|
104
|
+
|
|
105
|
+
### `answer.extractionTimeoutMs`
|
|
106
|
+
|
|
107
|
+
- type: positive number
|
|
108
|
+
- default: `30000`
|
|
109
|
+
- effect: per-attempt extraction timeout in milliseconds
|
|
110
|
+
|
|
111
|
+
### `answer.extractionRetries`
|
|
112
|
+
|
|
113
|
+
- type: integer from `0` to `3`
|
|
114
|
+
- default: `1`
|
|
115
|
+
- effect: number of retry attempts after raw JSON parsing fails; retries include the parse error and previous response as feedback
|
|
116
|
+
|
|
117
|
+
## Behaviour
|
|
118
|
+
|
|
119
|
+
### `behaviour.autoSubmitWhenAnsweredWithoutNotes`
|
|
120
|
+
|
|
121
|
+
- type: boolean
|
|
122
|
+
- default: `false`
|
|
123
|
+
- effect: when enabled, a fully answered ask flow with no notes can auto-submit from the review tab
|
|
124
|
+
|
|
125
|
+
### `behaviour.confirmDismissWhenDirty`
|
|
126
|
+
|
|
127
|
+
- type: boolean
|
|
128
|
+
- default: `true`
|
|
129
|
+
- effect: when enabled, discarding a dirty ask flow requires a second cancel/dismiss action
|
|
130
|
+
- the warning stays visible until the user changes tabs in the ask flow
|
|
131
|
+
- dirty means there are saved answers/notes or unsaved editor draft text
|
|
132
|
+
|
|
133
|
+
### `behaviour.doublePressReviewShortcuts`
|
|
134
|
+
|
|
135
|
+
- type: boolean
|
|
136
|
+
- default: `true`
|
|
137
|
+
- effect: when enabled, review-tab number shortcuts (`1`, `2`, `3`) only trigger after pressing the same key twice
|
|
138
|
+
- the review screen shows an inline hint and keeps the pending shortcut armed until another review shortcut is pressed or the user leaves the tab
|
|
139
|
+
|
|
140
|
+
### `behaviour.presentSingleAsMulti`
|
|
141
|
+
|
|
142
|
+
- type: boolean
|
|
143
|
+
- default: `false`
|
|
144
|
+
- effect: future ask flows render requested `single` questions as `multi` questions
|
|
145
|
+
- result: the question keeps `type: "single"` and adds `presentedType: "multi"`; result text uses one compact note when any answered questions were presented differently
|
|
146
|
+
- scope: this is a default presentation policy for new/replayed ask flows; it is not hot-applied to the current ask flow
|
|
147
|
+
- current-flow override: use the configurable main-flow `changeQuestionType` hotkey (default `t`) to change the active question type live: non-preview questions toggle `single <-> multi`; preview questions toggle `preview <-> multi`
|
|
148
|
+
- destructive confirmation: changing `multi -> single` with multiple selected answers requires pressing the type hotkey again; the pending confirmation has no timeout and clears when another navigation/action is used
|
|
149
|
+
|
|
150
|
+
### `behaviour.showFooterHints`
|
|
151
|
+
|
|
152
|
+
- type: boolean
|
|
153
|
+
- default: `true`
|
|
154
|
+
- effect: when disabled, the ask flow hides the footer keymap hints
|
|
155
|
+
|
|
156
|
+
## Notifications
|
|
157
|
+
|
|
158
|
+
Notifications are best-effort external alerts emitted once per ask session, when the ask UI opens and is waiting for input.
|
|
159
|
+
|
|
160
|
+
### `notifications.enabled`
|
|
161
|
+
|
|
162
|
+
- type: boolean
|
|
163
|
+
- default: `true`
|
|
164
|
+
- effect: enables or disables external ask notifications
|
|
165
|
+
- settings UI: this is the only notification field toggled individually by `/ask-settings` or `?` in the ask flow
|
|
166
|
+
|
|
167
|
+
### `notifications.channels`
|
|
168
|
+
|
|
169
|
+
- type: array
|
|
170
|
+
- default: `["bell"]`
|
|
171
|
+
- supported channels:
|
|
172
|
+
- `"bell"` writes BEL (`\u0007`)
|
|
173
|
+
- `"osc9"` writes an OSC 9 terminal notification
|
|
174
|
+
- `"osc777"` writes an OSC 777 title/body notification
|
|
175
|
+
- `{ "type": "command", "command": string }` runs a shell command
|
|
176
|
+
- effect: channels run in order; failures are ignored and never fail the ask flow
|
|
177
|
+
- invalid channels are skipped; if none are valid, pi-ask falls back to `["bell"]`
|
|
178
|
+
|
|
179
|
+
Notification text:
|
|
180
|
+
|
|
181
|
+
```txt
|
|
182
|
+
Question waiting: <label or prompt>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Command channels receive these environment variables:
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
ASK_NOTIFY_EVENT=question.waiting
|
|
189
|
+
ASK_NOTIFY_TITLE="pi ask"
|
|
190
|
+
ASK_NOTIFY_MESSAGE="Question waiting: <label or prompt>"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
cmux example:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"type": "command",
|
|
198
|
+
"command": "cmux notify --title \"$ASK_NOTIFY_TITLE\" --body \"$ASK_NOTIFY_MESSAGE\""
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Keymaps
|
|
203
|
+
|
|
204
|
+
`keymaps` is context-aware. Each action accepts either one key id string or an array of key id strings.
|
|
205
|
+
Arrays are aliases: any listed key triggers the same action.
|
|
206
|
+
|
|
207
|
+
### Defaults
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
"keymaps": {
|
|
211
|
+
"global": {
|
|
212
|
+
"dismiss": ["ctrl+c"],
|
|
213
|
+
"settings": ["?"]
|
|
214
|
+
},
|
|
215
|
+
"main": {
|
|
216
|
+
"confirm": ["enter"],
|
|
217
|
+
"cancel": ["esc"],
|
|
218
|
+
"changeQuestionType": ["t"],
|
|
219
|
+
"toggle": ["space"],
|
|
220
|
+
"nextTab": ["tab", "right"],
|
|
221
|
+
"previousTab": ["shift+tab", "left"],
|
|
222
|
+
"nextOption": ["down"],
|
|
223
|
+
"previousOption": ["up"],
|
|
224
|
+
"optionNote": ["n"],
|
|
225
|
+
"questionNote": ["shift+n"]
|
|
226
|
+
},
|
|
227
|
+
"editor": {
|
|
228
|
+
"submit": ["enter"],
|
|
229
|
+
"close": ["esc"],
|
|
230
|
+
"nextTabWhenEmpty": ["tab", "right"],
|
|
231
|
+
"previousTabWhenEmpty": ["shift+tab", "left"],
|
|
232
|
+
"nextOptionWhenEmpty": ["down"],
|
|
233
|
+
"previousOptionWhenEmpty": ["up"]
|
|
234
|
+
},
|
|
235
|
+
"noteEditor": {
|
|
236
|
+
"save": ["enter"],
|
|
237
|
+
"close": ["esc"],
|
|
238
|
+
"nextTabWhenEmpty": ["tab", "right"],
|
|
239
|
+
"previousTabWhenEmpty": ["shift+tab", "left"],
|
|
240
|
+
"nextOptionWhenEmpty": ["down"],
|
|
241
|
+
"previousOptionWhenEmpty": ["up"]
|
|
242
|
+
},
|
|
243
|
+
"settingsModal": {
|
|
244
|
+
"close": ["esc", "ctrl+c", "?"],
|
|
245
|
+
"nextOption": ["down"],
|
|
246
|
+
"previousOption": ["up"],
|
|
247
|
+
"toggle": ["enter", "space"]
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Contexts
|
|
253
|
+
|
|
254
|
+
- `global`: active in the main ask flow and editors; duplicates with those contexts are invalid
|
|
255
|
+
- `main`: question and review flow
|
|
256
|
+
- `editor`: custom answer editor
|
|
257
|
+
- `noteEditor`: question/option note editor
|
|
258
|
+
- `settingsModal`: `/ask-settings` and `?` settings overlay
|
|
259
|
+
|
|
260
|
+
### Allowed bindings
|
|
261
|
+
|
|
262
|
+
Each action accepts any `pi-tui` key id string, as long as it is:
|
|
263
|
+
|
|
264
|
+
- supported by `pi-tui`
|
|
265
|
+
- not a fixed numeric shortcut (`1` through `9`)
|
|
266
|
+
- not duplicated within the same context
|
|
267
|
+
- not duplicated between `global` and `main`, `editor`, or `noteEditor`
|
|
268
|
+
|
|
269
|
+
Examples of valid bindings:
|
|
270
|
+
|
|
271
|
+
- `esc`
|
|
272
|
+
- `ctrl+c`
|
|
273
|
+
- `space`
|
|
274
|
+
- `enter`
|
|
275
|
+
- `n`
|
|
276
|
+
- `shift+n`
|
|
277
|
+
- `alt+f7`
|
|
278
|
+
- `ctrl+[`
|
|
279
|
+
- `ctrl+shift+p`
|
|
280
|
+
- `super+k`
|
|
281
|
+
|
|
282
|
+
### Accepted alias normalization
|
|
283
|
+
|
|
284
|
+
Common aliases are normalized to canonical `pi-tui`-style strings.
|
|
285
|
+
|
|
286
|
+
Examples:
|
|
287
|
+
|
|
288
|
+
- `escape` -> `esc`
|
|
289
|
+
- `return` -> `enter`
|
|
290
|
+
- `control+c` -> `ctrl+c`
|
|
291
|
+
- `Shift+N` -> `shift+n`
|
|
292
|
+
- `pageup` -> `pageUp`
|
|
293
|
+
- `pagedown` -> `pageDown`
|
|
294
|
+
|
|
295
|
+
### Fixed bindings
|
|
296
|
+
|
|
297
|
+
These are intentionally not configurable:
|
|
298
|
+
|
|
299
|
+
- `1..9` triggers option/review shortcuts
|
|
300
|
+
- when `behaviour.doublePressReviewShortcuts` is enabled, review-tab shortcuts `1`, `2`, and `3` require the same key twice
|
|
301
|
+
- `@` remains the file-reference affordance in editors
|
|
302
|
+
|
|
303
|
+
## Invalid keymaps behavior
|
|
304
|
+
|
|
305
|
+
If configured keymaps are invalid:
|
|
306
|
+
|
|
307
|
+
- valid `behaviour`, `notifications`, and `answer` settings still load
|
|
308
|
+
- invalid `keymaps` fall back to default keymaps for the current session
|
|
309
|
+
- ask remains usable
|
|
310
|
+
- a warning notice is shown
|
|
311
|
+
- after fixing the file, run `/reload` or restart pi
|
|
312
|
+
|
|
313
|
+
Invalid keymaps include:
|
|
314
|
+
|
|
315
|
+
- missing one of the required contexts or actions
|
|
316
|
+
- unsupported key syntax
|
|
317
|
+
- duplicate bindings within one context
|
|
318
|
+
- duplicate bindings between `global` and `main`, `editor`, or `noteEditor`
|
|
319
|
+
- use of fixed numeric shortcuts (`1` through `9`)
|
|
320
|
+
|
|
321
|
+
## Example custom config
|
|
322
|
+
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"schemaVersion": 5,
|
|
326
|
+
"answer": {
|
|
327
|
+
"extractionRetries": 1,
|
|
328
|
+
"extractionTimeoutMs": 30000,
|
|
329
|
+
"extractionModels": [
|
|
330
|
+
{ "provider": "openai-codex", "id": "<model-id>" }
|
|
331
|
+
]
|
|
332
|
+
},
|
|
333
|
+
"behaviour": {
|
|
334
|
+
"autoSubmitWhenAnsweredWithoutNotes": true,
|
|
335
|
+
"confirmDismissWhenDirty": true,
|
|
336
|
+
"doublePressReviewShortcuts": true,
|
|
337
|
+
"presentSingleAsMulti": false,
|
|
338
|
+
"showFooterHints": false
|
|
339
|
+
},
|
|
340
|
+
"keymaps": {
|
|
341
|
+
"global": {
|
|
342
|
+
"dismiss": ["ctrl+c"],
|
|
343
|
+
"settings": ["?"]
|
|
344
|
+
},
|
|
345
|
+
"main": {
|
|
346
|
+
"confirm": ["ctrl+k"],
|
|
347
|
+
"cancel": ["q"],
|
|
348
|
+
"toggle": ["ctrl+t"],
|
|
349
|
+
"changeQuestionType": ["t"],
|
|
350
|
+
"nextTab": ["tab", "right"],
|
|
351
|
+
"previousTab": ["shift+tab", "left"],
|
|
352
|
+
"nextOption": ["down"],
|
|
353
|
+
"previousOption": ["up"],
|
|
354
|
+
"optionNote": ["x"],
|
|
355
|
+
"questionNote": ["shift+x"]
|
|
356
|
+
},
|
|
357
|
+
"editor": {
|
|
358
|
+
"submit": ["ctrl+k"],
|
|
359
|
+
"close": ["q"],
|
|
360
|
+
"nextTabWhenEmpty": ["tab", "right"],
|
|
361
|
+
"previousTabWhenEmpty": ["shift+tab", "left"],
|
|
362
|
+
"nextOptionWhenEmpty": ["down"],
|
|
363
|
+
"previousOptionWhenEmpty": ["up"]
|
|
364
|
+
},
|
|
365
|
+
"noteEditor": {
|
|
366
|
+
"save": ["ctrl+k"],
|
|
367
|
+
"close": ["q"],
|
|
368
|
+
"nextTabWhenEmpty": ["tab", "right"],
|
|
369
|
+
"previousTabWhenEmpty": ["shift+tab", "left"],
|
|
370
|
+
"nextOptionWhenEmpty": ["down"],
|
|
371
|
+
"previousOptionWhenEmpty": ["up"]
|
|
372
|
+
},
|
|
373
|
+
"settingsModal": {
|
|
374
|
+
"close": ["esc", "ctrl+c", "?"],
|
|
375
|
+
"nextOption": ["j", "down"],
|
|
376
|
+
"previousOption": ["k", "up"],
|
|
377
|
+
"toggle": ["enter", "space"]
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
"notifications": {
|
|
381
|
+
"enabled": true,
|
|
382
|
+
"channels": [
|
|
383
|
+
{
|
|
384
|
+
"type": "command",
|
|
385
|
+
"command": "cmux notify --title \"$ASK_NOTIFY_TITLE\" --body \"$ASK_NOTIFY_MESSAGE\""
|
|
386
|
+
}
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Agent editing rule
|
|
393
|
+
|
|
394
|
+
When editing this config for a user:
|
|
395
|
+
|
|
396
|
+
- preserve unrelated fields
|
|
397
|
+
- keep `schemaVersion` at `5`
|
|
398
|
+
- preserve `answer.extractionModels` as explicit provider/id pairs
|
|
399
|
+
- keep `answer.extractionRetries` between `0` and `3`
|
|
400
|
+
- do not assign fixed numeric shortcuts (`1` through `9`) to configurable actions
|
|
401
|
+
- do not create duplicate bindings within a context or between `global` and `main`, `editor`, or `noteEditor`
|
|
402
|
+
- preserve existing `notifications.channels` unless the user asks to change notification targets
|
|
403
|
+
- only toggle `notifications.enabled` unless the user asks to configure channels
|
|
404
|
+
- use the settings reset action only when the user explicitly asks to restore pi-ask defaults
|
|
405
|
+
- use a `cmux notify` command channel when the user asks for cmux notifications
|
|
406
|
+
- after changing the file, tell the user to run `/reload` or restart pi
|