@sagmans/dsh-tui 0.2.0 → 0.4.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.
Files changed (174) hide show
  1. package/README.md +282 -25
  2. package/cordis.patch.yml +14 -0
  3. package/lib/agent/model.d.ts +26 -0
  4. package/lib/agent/model.d.ts.map +1 -1
  5. package/lib/agent/model.js +41 -0
  6. package/lib/agent/model.js.map +1 -1
  7. package/lib/agent/projections.d.ts +22 -6
  8. package/lib/agent/projections.d.ts.map +1 -1
  9. package/lib/agent/projections.js +21 -10
  10. package/lib/agent/projections.js.map +1 -1
  11. package/lib/agent/prompt-history.d.ts +89 -0
  12. package/lib/agent/prompt-history.d.ts.map +1 -0
  13. package/lib/agent/prompt-history.js +380 -0
  14. package/lib/agent/prompt-history.js.map +1 -0
  15. package/lib/agent/status.d.ts +16 -0
  16. package/lib/agent/status.d.ts.map +1 -1
  17. package/lib/agent/status.js +3 -0
  18. package/lib/agent/status.js.map +1 -1
  19. package/lib/cards.d.ts +1 -1
  20. package/lib/cards.d.ts.map +1 -1
  21. package/lib/cards.js +4 -3
  22. package/lib/cards.js.map +1 -1
  23. package/lib/gates.d.ts +145 -2
  24. package/lib/gates.d.ts.map +1 -1
  25. package/lib/gates.js +335 -40
  26. package/lib/gates.js.map +1 -1
  27. package/lib/herdr/client.d.ts +57 -0
  28. package/lib/herdr/client.d.ts.map +1 -0
  29. package/lib/herdr/client.js +218 -0
  30. package/lib/herdr/client.js.map +1 -0
  31. package/lib/herdr/constants.d.ts +93 -0
  32. package/lib/herdr/constants.d.ts.map +1 -0
  33. package/lib/herdr/constants.js +79 -0
  34. package/lib/herdr/constants.js.map +1 -0
  35. package/lib/herdr/reporter.d.ts +60 -0
  36. package/lib/herdr/reporter.d.ts.map +1 -0
  37. package/lib/herdr/reporter.js +217 -0
  38. package/lib/herdr/reporter.js.map +1 -0
  39. package/lib/herdr/state.d.ts +57 -0
  40. package/lib/herdr/state.d.ts.map +1 -0
  41. package/lib/herdr/state.js +62 -0
  42. package/lib/herdr/state.js.map +1 -0
  43. package/lib/index.d.ts.map +1 -1
  44. package/lib/index.js +631 -118
  45. package/lib/index.js.map +1 -1
  46. package/lib/input/actions.d.ts +136 -0
  47. package/lib/input/actions.d.ts.map +1 -0
  48. package/lib/input/actions.js +743 -0
  49. package/lib/input/actions.js.map +1 -0
  50. package/lib/input/ghost.d.ts +46 -0
  51. package/lib/input/ghost.d.ts.map +1 -0
  52. package/lib/input/ghost.js +58 -0
  53. package/lib/input/ghost.js.map +1 -0
  54. package/lib/input/keymap-settings.d.ts +21 -0
  55. package/lib/input/keymap-settings.d.ts.map +1 -0
  56. package/lib/input/keymap-settings.js +28 -0
  57. package/lib/input/keymap-settings.js.map +1 -0
  58. package/lib/input/keymap.d.ts +91 -0
  59. package/lib/input/keymap.d.ts.map +1 -0
  60. package/lib/input/keymap.js +172 -0
  61. package/lib/input/keymap.js.map +1 -0
  62. package/lib/input/match.d.ts +10 -0
  63. package/lib/input/match.d.ts.map +1 -0
  64. package/lib/input/match.js +83 -0
  65. package/lib/input/match.js.map +1 -0
  66. package/lib/input/submission.d.ts +29 -1
  67. package/lib/input/submission.d.ts.map +1 -1
  68. package/lib/input/submission.js +33 -2
  69. package/lib/input/submission.js.map +1 -1
  70. package/lib/input.d.ts +17 -0
  71. package/lib/input.d.ts.map +1 -0
  72. package/lib/input.js +27 -0
  73. package/lib/input.js.map +1 -0
  74. package/lib/keys-command.d.ts +16 -0
  75. package/lib/keys-command.d.ts.map +1 -0
  76. package/lib/keys-command.js +60 -0
  77. package/lib/keys-command.js.map +1 -0
  78. package/lib/queue.d.ts +6 -0
  79. package/lib/queue.d.ts.map +1 -0
  80. package/lib/queue.js +68 -0
  81. package/lib/queue.js.map +1 -0
  82. package/lib/settings-notice.d.ts +19 -0
  83. package/lib/settings-notice.d.ts.map +1 -0
  84. package/lib/settings-notice.js +30 -0
  85. package/lib/settings-notice.js.map +1 -0
  86. package/lib/stash/lock.d.ts +72 -0
  87. package/lib/stash/lock.d.ts.map +1 -0
  88. package/lib/stash/lock.js +374 -0
  89. package/lib/stash/lock.js.map +1 -0
  90. package/lib/stash/paths.d.ts +22 -0
  91. package/lib/stash/paths.d.ts.map +1 -0
  92. package/lib/stash/paths.js +83 -0
  93. package/lib/stash/paths.js.map +1 -0
  94. package/lib/stash/private-fs.d.ts +61 -0
  95. package/lib/stash/private-fs.d.ts.map +1 -0
  96. package/lib/stash/private-fs.js +379 -0
  97. package/lib/stash/private-fs.js.map +1 -0
  98. package/lib/stash/schema.d.ts +57 -0
  99. package/lib/stash/schema.d.ts.map +1 -0
  100. package/lib/stash/schema.js +127 -0
  101. package/lib/stash/schema.js.map +1 -0
  102. package/lib/stash/store.d.ts +92 -0
  103. package/lib/stash/store.d.ts.map +1 -0
  104. package/lib/stash/store.js +262 -0
  105. package/lib/stash/store.js.map +1 -0
  106. package/lib/stash.d.ts +91 -0
  107. package/lib/stash.d.ts.map +1 -0
  108. package/lib/stash.js +296 -0
  109. package/lib/stash.js.map +1 -0
  110. package/lib/theme-settings.d.ts +72 -8
  111. package/lib/theme-settings.d.ts.map +1 -1
  112. package/lib/theme-settings.js +125 -5
  113. package/lib/theme-settings.js.map +1 -1
  114. package/lib/theme-tokens.d.ts +4 -4
  115. package/lib/theme-tokens.d.ts.map +1 -1
  116. package/lib/theme-tokens.js +39 -5
  117. package/lib/theme-tokens.js.map +1 -1
  118. package/lib/todo-guard.d.ts +116 -0
  119. package/lib/todo-guard.d.ts.map +1 -0
  120. package/lib/todo-guard.js +259 -0
  121. package/lib/todo-guard.js.map +1 -0
  122. package/lib/ui/editor.d.ts +58 -1
  123. package/lib/ui/editor.d.ts.map +1 -1
  124. package/lib/ui/editor.js +174 -19
  125. package/lib/ui/editor.js.map +1 -1
  126. package/lib/ui/frame.d.ts +54 -0
  127. package/lib/ui/frame.d.ts.map +1 -0
  128. package/lib/ui/frame.js +79 -0
  129. package/lib/ui/frame.js.map +1 -0
  130. package/lib/ui/gate-input.d.ts +20 -0
  131. package/lib/ui/gate-input.d.ts.map +1 -0
  132. package/lib/ui/gate-input.js +96 -0
  133. package/lib/ui/gate-input.js.map +1 -0
  134. package/lib/ui/history-picker.d.ts +15 -0
  135. package/lib/ui/history-picker.d.ts.map +1 -0
  136. package/lib/ui/history-picker.js +26 -0
  137. package/lib/ui/history-picker.js.map +1 -0
  138. package/lib/ui/markdown.d.ts +11 -2
  139. package/lib/ui/markdown.d.ts.map +1 -1
  140. package/lib/ui/markdown.js +25 -6
  141. package/lib/ui/markdown.js.map +1 -1
  142. package/lib/ui/mermaid.d.ts +44 -0
  143. package/lib/ui/mermaid.d.ts.map +1 -0
  144. package/lib/ui/mermaid.js +178 -0
  145. package/lib/ui/mermaid.js.map +1 -0
  146. package/lib/ui/picker.d.ts +40 -8
  147. package/lib/ui/picker.d.ts.map +1 -1
  148. package/lib/ui/picker.js +79 -24
  149. package/lib/ui/picker.js.map +1 -1
  150. package/lib/ui/prompt.d.ts +32 -0
  151. package/lib/ui/prompt.d.ts.map +1 -0
  152. package/lib/ui/prompt.js +49 -0
  153. package/lib/ui/prompt.js.map +1 -0
  154. package/lib/ui/queue.d.ts +24 -0
  155. package/lib/ui/queue.d.ts.map +1 -0
  156. package/lib/ui/queue.js +57 -0
  157. package/lib/ui/queue.js.map +1 -0
  158. package/lib/ui/stash-picker.d.ts +43 -0
  159. package/lib/ui/stash-picker.d.ts.map +1 -0
  160. package/lib/ui/stash-picker.js +78 -0
  161. package/lib/ui/stash-picker.js.map +1 -0
  162. package/lib/ui/status.d.ts +6 -0
  163. package/lib/ui/status.d.ts.map +1 -1
  164. package/lib/ui/status.js +15 -0
  165. package/lib/ui/status.js.map +1 -1
  166. package/lib/ui/view.d.ts +22 -2
  167. package/lib/ui/view.d.ts.map +1 -1
  168. package/lib/ui/view.js +84 -24
  169. package/lib/ui/view.js.map +1 -1
  170. package/lib/work.d.ts +51 -1
  171. package/lib/work.d.ts.map +1 -1
  172. package/lib/work.js +53 -1
  173. package/lib/work.js.map +1 -1
  174. package/package.json +7 -2
package/lib/gates.js CHANGED
@@ -1,4 +1,7 @@
1
1
  import { matchesKey } from '@earendil-works/pi-tui';
2
+ import { actionLabel, keyName, keysFor, matchesAction, moveHint } from "./input/actions.js";
3
+ import { pastedText } from "./input.js";
4
+ import { matchScore } from "./input/match.js";
2
5
  function lines(value) {
3
6
  return value.split('\n').filter(line => line.trim() !== '');
4
7
  }
@@ -12,10 +15,14 @@ function lines(value) {
12
15
  export class ApprovalGate {
13
16
  toolName;
14
17
  reason;
18
+ keys;
15
19
  outcome;
16
- constructor(toolName, reason) {
20
+ constructor(toolName, reason,
21
+ /** The keys in force, read per press so a settings edit lands on the next key. */
22
+ keys) {
17
23
  this.toolName = toolName;
18
24
  this.reason = reason;
25
+ this.keys = keys;
19
26
  }
20
27
  get resolved() {
21
28
  return this.outcome !== undefined;
@@ -24,11 +31,11 @@ export class ApprovalGate {
24
31
  handleKey(data) {
25
32
  if (this.outcome !== undefined)
26
33
  return undefined;
27
- if (matchesKey(data, 'y'))
34
+ if (matchesAction(this.keys(), 'gate.allow', data))
28
35
  this.outcome = 'allowed-once';
29
- else if (matchesKey(data, 'n'))
36
+ else if (matchesAction(this.keys(), 'gate.reject', data))
30
37
  this.outcome = 'rejected';
31
- else if (matchesKey(data, 'escape'))
38
+ else if (matchesAction(this.keys(), 'gate.cancel', data))
32
39
  this.outcome = 'cancelled';
33
40
  return this.outcome;
34
41
  }
@@ -40,8 +47,15 @@ export class ApprovalGate {
40
47
  kind: 'approval',
41
48
  title: `approval needed · ${this.toolName}`,
42
49
  detail: this.reason === undefined ? [] : lines(this.reason),
50
+ answerInput: undefined,
51
+ optionOffset: 0,
43
52
  options: [],
44
- hint: this.outcome === undefined ? 'y allow once · n reject · esc cancel' : 'decided',
53
+ custom: undefined,
54
+ hint: this.outcome === undefined
55
+ ? ['gate.allow', 'gate.reject', 'gate.cancel']
56
+ .map(id => keysFor(this.keys(), id).map(key => `${keyName(key)} ${actionLabel(id)}`).join(' · '))
57
+ .join(' · ')
58
+ : 'decided',
45
59
  };
46
60
  }
47
61
  }
@@ -74,6 +88,7 @@ export function toGateQuestions(request) {
74
88
  questions.push({
75
89
  id: entry.id,
76
90
  question: typeof entry.question === 'string' ? entry.question : 'question',
91
+ header: typeof entry.header === 'string' ? entry.header : undefined,
77
92
  detail: typeof entry.detail === 'string' ? entry.detail : undefined,
78
93
  options,
79
94
  multiSelect: entry.multiSelect === true,
@@ -81,6 +96,53 @@ export function toGateQuestions(request) {
81
96
  }
82
97
  return questions;
83
98
  }
99
+ /** How many option rows a question shows at once, so a catalog-sized list leaves the editor in view. */
100
+ const QUESTION_WINDOW = 12;
101
+ /** The number the free-text row answers for. It sits below the window, so drawn numbering runs 1..n then 0. */
102
+ export const CUSTOM_ROW_NUMBER = 0;
103
+ /** The label a question earns for an answer the model did not list. */
104
+ const CUSTOM_ROW_LABEL = 'other';
105
+ /** What the free-text row does, said where the reader decides. */
106
+ const CUSTOM_ROW_DESCRIPTION = 'type your own answer';
107
+ /** How the list hint names that row, which the row itself already labels. */
108
+ const CUSTOM_ROW_SHORTHAND = `${CUSTOM_ROW_NUMBER} answer freely`;
109
+ /**
110
+ * How a hint names the keys of one action.
111
+ *
112
+ * A hint is prose about what a key does here, so the word comes from the card
113
+ * rather than from the catalog row, which has to read well out of context too.
114
+ */
115
+ function namedKeys(map, id, verb) {
116
+ // One verb for the action, however many keys reach it: a hint that repeated
117
+ // the word would read as two actions rather than two ways to do one.
118
+ return `${keysFor(map, id).map(keyName).join('/')} ${verb}`;
119
+ }
120
+ /**
121
+ * How the free-text row spells the keys that leave it.
122
+ *
123
+ * A text field keeps its own exits: the arrows and escape are the field's, not
124
+ * the question's, so a reader who moved question.up or question.skip somewhere
125
+ * else still leaves with these. The hint therefore names them as the terminal
126
+ * spells them instead of promising a key the row does not answer.
127
+ */
128
+ const CUSTOM_ROW_EXITS = '↑↓ or esc';
129
+ /** The keys that answer the free-text row, where typing is the answer rather than a filter. */
130
+ function customHint(map) {
131
+ return `type or paste an answer · ${namedKeys(map, 'question.confirm', 'confirm')} · ${CUSTOM_ROW_EXITS} to options`;
132
+ }
133
+ /**
134
+ * The question-id suffix that declares a typed answer a credential. The seam
135
+ * has no field for it, so a caller marks its own id and the gate reads that
136
+ * declaration rather than the wording: ids are caller-owned, and a question
137
+ * that merely mentions a key must still show the answer its author meant read.
138
+ */
139
+ const SECRET_ID_SUFFIX = ':secret';
140
+ /** The free-text row's label when the answer is a credential, so the reader sees what they hand over. */
141
+ const SECRET_ROW_LABEL = 'API KEY';
142
+ /** Whether a question declares its typed answer a credential through its id. */
143
+ function declaresSecret(id) {
144
+ return id.endsWith(SECRET_ID_SUFFIX);
145
+ }
84
146
  /**
85
147
  * A pending batch of questions.
86
148
  *
@@ -91,90 +153,287 @@ export function toGateQuestions(request) {
91
153
  */
92
154
  export class QuestionGate {
93
155
  questions;
156
+ input;
157
+ keys;
94
158
  index = 0;
95
159
  cursor = 0;
96
160
  typed = '';
161
+ /** Whether the cursor is on the free-text row. */
162
+ atCustom = false;
163
+ /**
164
+ * The row an escape from the free-text row returns to.
165
+ *
166
+ * It is the row the reader last acted on — walked to, picked by its number, or
167
+ * toggled — because that is the option they were looking at when they decided
168
+ * to answer freely, and it is not always the row the cursor still stands on: a
169
+ * digit picks by number without walking anywhere.
170
+ */
171
+ customFrom = 0;
97
172
  chosen = [];
98
173
  custom = [];
99
174
  finished = false;
100
- constructor(questions) {
175
+ constructor(questions,
176
+ /** The editor every typed answer is written in, whichever row asks for it. */
177
+ input,
178
+ /** The keys in force, read per press so a settings edit lands on the next key. */
179
+ keys) {
101
180
  this.questions = questions;
181
+ this.input = input;
182
+ this.keys = keys;
102
183
  for (const _ of questions) {
103
184
  this.chosen.push([]);
104
185
  this.custom.push(undefined);
105
186
  }
187
+ this.resetInput();
188
+ }
189
+ /**
190
+ * Empty the editor for the question now under the cursor.
191
+ *
192
+ * The editor belongs to the surface and outlives one question, so an answer
193
+ * must never cross from the last question into the next — or from a gate that
194
+ * was abandoned into the one that follows it. Its mode follows the question
195
+ * for the same reason: a credential must not be shown because the last
196
+ * question was not one.
197
+ */
198
+ resetInput() {
199
+ this.input.setText('');
200
+ this.input.setMode?.(this.current !== undefined && declaresSecret(this.current.id) ? 'secret' : 'answer');
106
201
  }
107
202
  get resolved() {
108
203
  return this.finished;
109
204
  }
205
+ /**
206
+ * Stop a question whose caller is gone.
207
+ *
208
+ * WHY: an aborted call has no reader for the answer, and a live gate would
209
+ * otherwise keep the keyboard — and the borrowed editor — until someone
210
+ * typed into a call that had already ended.
211
+ */
212
+ cancel() {
213
+ this.finished = true;
214
+ }
110
215
  get current() {
111
216
  return this.questions[this.index];
112
217
  }
218
+ /**
219
+ * Options the typed filter leaves, in the order they were listed.
220
+ *
221
+ * The order is not the score order a picker uses: a digit answers by
222
+ * position, and re-ranking rows would move the number the reader just read.
223
+ */
224
+ matched(question) {
225
+ const needle = this.typed.trim();
226
+ return question.options
227
+ .map((option, position) => ({ option, position }))
228
+ .filter(({ option }) => matchScore(needle, `${option.label} ${option.description ?? ''}`) !== undefined);
229
+ }
230
+ /**
231
+ * The rows the keys and the card agree on: the filter, then a window around
232
+ * the cursor, because a list as long as a provider catalog would otherwise
233
+ * push the editor off the screen.
234
+ */
235
+ windowed(question) {
236
+ const matched = this.matched(question);
237
+ const cursor = Math.min(this.cursor, Math.max(0, matched.length - 1));
238
+ const start = Math.max(0, Math.min(cursor - Math.floor(QUESTION_WINDOW / 2), matched.length - QUESTION_WINDOW));
239
+ return { rows: matched.slice(start, start + QUESTION_WINDOW), start, cursor };
240
+ }
241
+ /** The row under the cursor, as the filter leaves it. */
242
+ currentRow(question) {
243
+ const matched = this.matched(question);
244
+ return matched[Math.min(this.cursor, Math.max(0, matched.length - 1))];
245
+ }
246
+ /** Take or drop one source option, by single-select replacement or multi-select toggle. */
247
+ pick(position) {
248
+ const question = this.current;
249
+ const option = question?.options[position];
250
+ if (question === undefined || option === undefined)
251
+ return;
252
+ const chosen = this.chosen[this.index] ?? [];
253
+ this.chosen[this.index] = chosen.includes(option.label)
254
+ ? chosen.filter(label => label !== option.label)
255
+ : question.multiSelect === true ? [...chosen, option.label] : [option.label];
256
+ }
257
+ /**
258
+ * Whether a keystroke is answer text rather than a filter.
259
+ *
260
+ * A question without options has no list to filter, and the free-text row is
261
+ * where a question with options collects an answer the model did not list.
262
+ */
263
+ typingAnswer(question) {
264
+ return question.options.length === 0 || this.atCustom;
265
+ }
266
+ /** Add text to the filter, or to the answer the current row collects. */
267
+ absorb(text) {
268
+ const question = this.current;
269
+ if (question === undefined || text === '')
270
+ return;
271
+ if (this.typingAnswer(question)) {
272
+ // The editor decides what an insertion is: a paste arrives as one edit,
273
+ // and a multi-character chunk is one undo step rather than many.
274
+ this.input.handleInput(text);
275
+ return;
276
+ }
277
+ this.typed += text;
278
+ this.cursor = 0;
279
+ this.customFrom = 0;
280
+ }
113
281
  /** Apply one key press; returns the batch answer the first time it completes. */
114
282
  handleKey(data) {
115
283
  const question = this.current;
116
284
  if (this.finished || question === undefined)
117
285
  return undefined;
118
- if (matchesKey(data, 'up')) {
119
- this.cursor = Math.max(0, this.cursor - 1);
286
+ const paste = pastedText(data);
287
+ if (paste !== undefined) {
288
+ // An answer takes the paste sequence itself, because the editor reads it;
289
+ // a filter takes the text inside it, because nothing else would.
290
+ this.absorb(this.typingAnswer(question) ? data : paste);
120
291
  return undefined;
121
292
  }
122
- if (matchesKey(data, 'down')) {
123
- this.cursor = Math.min(Math.max(0, question.options.length - 1), this.cursor + 1);
293
+ // The free-text row is a text field, so the keys that walk or pick a list
294
+ // would otherwise take the very characters an answer is made of.
295
+ if (this.atCustom)
296
+ return this.handleCustomKey(data);
297
+ const matched = this.matched(question);
298
+ const keys = this.keys();
299
+ if (matchesAction(keys, 'question.up', data)) {
300
+ this.cursor = Math.max(0, this.cursor - 1);
301
+ this.customFrom = this.cursor;
124
302
  return undefined;
125
303
  }
126
- if (question.options.length > 0 && matchesKey(data, 'space')) {
127
- const option = question.options[this.cursor];
128
- if (option !== undefined) {
129
- const chosen = this.chosen[this.index] ?? [];
130
- this.chosen[this.index] = chosen.includes(option.label)
131
- ? chosen.filter(label => label !== option.label)
132
- : question.multiSelect ? [...chosen, option.label] : [option.label];
304
+ if (matchesAction(keys, 'question.down', data)) {
305
+ // Below the last option sits the free-text row, which is the second way
306
+ // to reach it; a list with nothing left to show steps straight onto it.
307
+ if (this.cursor >= matched.length - 1) {
308
+ this.atCustom = true;
309
+ }
310
+ else {
311
+ this.cursor += 1;
312
+ this.customFrom = this.cursor;
133
313
  }
134
314
  return undefined;
135
315
  }
136
- if (matchesKey(data, 'escape')) {
137
- this.confirm();
316
+ if (question.options.length > 0 && matchesAction(keys, 'question.toggle', data)) {
317
+ const row = this.currentRow(question);
318
+ if (row !== undefined)
319
+ this.pick(row.position);
320
+ this.customFrom = this.cursor;
321
+ return undefined;
322
+ }
323
+ if (matchesAction(keys, 'question.skip', data)) {
324
+ this.advance();
138
325
  return this.result();
139
326
  }
140
- if (matchesKey(data, 'enter')) {
327
+ if (matchesAction(keys, 'question.confirm', data)) {
328
+ const chosen = this.chosen[this.index] ?? [];
329
+ if (question.options.length > 0 && chosen.length === 0) {
330
+ // A reader who typed enough to narrow the list is naming the row it
331
+ // left under the cursor; one who typed an id the list does not hold is
332
+ // naming that instead, which is why the typed text becomes the answer.
333
+ const row = this.currentRow(question);
334
+ if (row !== undefined)
335
+ this.pick(row.position);
336
+ else if (this.typed.trim() !== '')
337
+ this.custom[this.index] = this.typed.trim();
338
+ }
141
339
  this.confirm();
142
340
  return this.result();
143
341
  }
144
342
  if (matchesKey(data, 'backspace')) {
343
+ // The same routing typing follows: a question without options has no
344
+ // filter to erase, and the delete belongs to the answer it collected.
345
+ if (this.typingAnswer(question)) {
346
+ this.input.handleInput(data);
347
+ return undefined;
348
+ }
145
349
  this.typed = this.typed.slice(0, -1);
350
+ this.cursor = 0;
146
351
  return undefined;
147
352
  }
148
353
  if (matchesKey(data, 'space')) {
149
- this.typed += ' ';
354
+ this.absorb(' ');
150
355
  return undefined;
151
356
  }
152
- if (/^[1-9]$/u.test(data)) {
153
- const option = question.options[Number.parseInt(data, 10) - 1];
154
- if (option !== undefined) {
155
- const chosen = this.chosen[this.index] ?? [];
156
- this.chosen[this.index] = chosen.includes(option.label)
157
- ? chosen.filter(label => label !== option.label)
158
- : question.multiSelect ? [...chosen, option.label] : [option.label];
357
+ if (question.options.length > 0 && /^[0-9]$/u.test(data)) {
358
+ const digit = Number.parseInt(data, 10);
359
+ if (digit === CUSTOM_ROW_NUMBER) {
360
+ this.atCustom = true;
361
+ return undefined;
362
+ }
363
+ const row = matched[digit - 1];
364
+ if (row !== undefined) {
365
+ this.pick(row.position);
366
+ this.customFrom = digit - 1;
159
367
  }
160
368
  return undefined;
161
369
  }
162
370
  if (data.length === 1 && data >= ' ')
163
- this.typed += data;
371
+ this.absorb(data);
372
+ return undefined;
373
+ }
374
+ /**
375
+ * One key press while the free-text row holds the cursor.
376
+ *
377
+ * Walking back to the list keeps whatever was typed, so a reader who changes
378
+ * their mind about answering freely has not lost the text yet. An escape
379
+ * leaves the row the same way, because a question skipped by accident is a
380
+ * question the reader has to answer again: from the list, where every other
381
+ * question is skipped, an escape skips this one too.
382
+ */
383
+ handleCustomKey(data) {
384
+ if (matchesAction(this.keys(), 'question.confirm', data)) {
385
+ this.confirm();
386
+ return this.result();
387
+ }
388
+ // The keys that leave a text field are the field's own, not the question's:
389
+ // a skip the reader moved elsewhere must not quietly mean "walk back". The
390
+ // hint spells these literally for the same reason (CUSTOM_ROW_EXITS).
391
+ if (matchesKey(data, 'up') || matchesKey(data, 'down')) {
392
+ this.atCustom = false;
393
+ return undefined;
394
+ }
395
+ if (matchesKey(data, 'escape')) {
396
+ const question = this.current;
397
+ const rows = question === undefined ? 0 : this.matched(question).length;
398
+ this.atCustom = false;
399
+ this.cursor = Math.min(this.customFrom, Math.max(0, rows - 1));
400
+ return undefined;
401
+ }
402
+ // Anything else is the editor's: movement, deletion, undo, and the keys
403
+ // that insert a character this gate has no business knowing about.
404
+ this.input.handleInput(data);
164
405
  return undefined;
165
406
  }
407
+ /** Take the answer the reader confirmed, then leave the question. */
166
408
  confirm() {
167
409
  const question = this.current;
168
410
  if (question === undefined)
169
411
  return;
170
- const typed = this.typed.trim();
171
- if (typed !== '')
172
- this.custom[this.index] = typed;
412
+ const text = this.input.getExpandedText().trim();
413
+ if (text !== '') {
414
+ this.custom[this.index] = text;
415
+ // The seam reads a single-select custom as the answer itself, so a label
416
+ // picked before it would be a second answer the caller has to reconcile.
417
+ if (question.multiSelect !== true)
418
+ this.chosen[this.index] = [];
419
+ }
420
+ this.advance();
421
+ }
422
+ /**
423
+ * Leave the current question for the next one.
424
+ *
425
+ * Typed text belongs to the question being left, so it never crosses into the
426
+ * next one — which is why a skipped question reports no typed answer at all.
427
+ */
428
+ advance() {
173
429
  this.typed = '';
430
+ this.atCustom = false;
431
+ this.customFrom = 0;
174
432
  this.cursor = 0;
175
433
  this.index += 1;
176
434
  if (this.index >= this.questions.length)
177
435
  this.finished = true;
436
+ this.resetInput();
178
437
  }
179
438
  result() {
180
439
  if (!this.finished)
@@ -191,25 +450,61 @@ export class QuestionGate {
191
450
  card() {
192
451
  const question = this.current;
193
452
  if (question === undefined) {
194
- return { kind: 'question', title: 'question', detail: [], options: [], hint: 'finishing' };
453
+ return { kind: 'question', title: 'question', detail: [], optionOffset: 0, options: [], custom: undefined, answerInput: undefined, hint: 'finishing' };
195
454
  }
196
455
  const chosen = this.chosen[this.index] ?? [];
197
456
  const detail = question.detail === undefined ? [] : lines(question.detail);
457
+ const heading = question.header === undefined ? '' : question.header + ' · ';
458
+ const title = `${heading}${question.question}${this.questions.length > 1 ? ` (${this.index + 1}/${this.questions.length})` : ''}`;
459
+ if (question.options.length === 0) {
460
+ return {
461
+ kind: 'question',
462
+ title,
463
+ detail,
464
+ optionOffset: 0,
465
+ options: [],
466
+ custom: undefined,
467
+ // The editor is the only place the text lands, so it is drawn even while
468
+ // empty: a question answered by typing needs somewhere to paste a key.
469
+ answerInput: this.input,
470
+ hint: `type or paste an answer · ${namedKeys(this.keys(), 'question.confirm', 'confirm')} · ${namedKeys(this.keys(), 'question.skip', 'skip')}`,
471
+ };
472
+ }
198
473
  if (this.typed !== '')
199
- detail.push(`typed: ${this.typed}`);
474
+ detail.push(`filter: ${this.typed}`);
475
+ // The editor holds the answer, so whether one has been written is its own
476
+ // answer to give; the card only decides where to draw it.
477
+ const written = this.input.getExpandedText() !== '';
478
+ const secret = declaresSecret(question.id);
479
+ const matched = this.matched(question);
480
+ const { rows, start, cursor } = this.windowed(question);
481
+ if (rows.length < matched.length)
482
+ detail.push(`showing ${start + 1}–${start + rows.length} of ${matched.length}`);
200
483
  return {
201
484
  kind: 'question',
202
- title: `${question.question}${this.questions.length > 1 ? ` (${this.index + 1}/${this.questions.length})` : ''}`,
485
+ title,
203
486
  detail,
204
- options: question.options.map((option, position) => ({
487
+ optionOffset: start,
488
+ options: rows.map(({ option }, position) => ({
205
489
  label: option.label,
206
490
  description: option.description,
207
- current: position === this.cursor,
491
+ // The free-text row wears the cursor when it holds it: a mark on a row
492
+ // the reader is not pointing at is a mark that lies.
493
+ current: !this.atCustom && start + position === cursor,
208
494
  selected: chosen.includes(option.label),
209
495
  })),
210
- hint: question.options.length === 0
211
- ? 'type an answer · enter confirm · esc skip'
212
- : `${question.multiSelect ? 'space toggle' : 'space select'} · digits pick · enter confirm · esc skip`,
496
+ custom: {
497
+ label: secret ? SECRET_ROW_LABEL : CUSTOM_ROW_LABEL,
498
+ description: CUSTOM_ROW_DESCRIPTION,
499
+ current: this.atCustom,
500
+ selected: this.atCustom || written,
501
+ },
502
+ // A written answer stays in view whether or not the cursor is on the row,
503
+ // because it is what an enter is about to send.
504
+ answerInput: this.atCustom || written ? this.input : undefined,
505
+ hint: this.atCustom
506
+ ? customHint(this.keys())
507
+ : `${namedKeys(this.keys(), 'question.toggle', question.multiSelect ? 'toggle' : 'select')} · digits pick · ${CUSTOM_ROW_SHORTHAND} · type to filter · ${namedKeys(this.keys(), 'question.confirm', 'confirm')} · ${namedKeys(this.keys(), 'question.skip', 'skip')}`,
213
508
  };
214
509
  }
215
510
  }
package/lib/gates.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"gates.js","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gates.js","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The Herdr socket.
3
+ *
4
+ * Every method resolves rather than throws: a multiplexer that is absent, busy,
5
+ * or restarting is not a failure this surface may surface to its reader, whose
6
+ * conversation is the thing on screen. The same reasoning keeps the transport
7
+ * off stdout and stderr — the alternate screen owns both.
8
+ */
9
+ import { type HerdrState, type SessionStartReason } from './constants.ts';
10
+ export type HerdrEnvironment = Readonly<Record<string, string | undefined>>;
11
+ export interface HerdrClientOptions {
12
+ readonly attempts?: number;
13
+ readonly timeoutMs?: number;
14
+ }
15
+ export interface StateReport {
16
+ readonly state: HerdrState;
17
+ readonly message: string | undefined;
18
+ readonly seq: number;
19
+ readonly sessionId: string | undefined;
20
+ }
21
+ export interface SessionReport {
22
+ readonly sessionId: string;
23
+ readonly seq: number;
24
+ readonly reason: SessionStartReason;
25
+ }
26
+ export interface HerdrClient {
27
+ /** Whether Herdr started this process and asked to be told about it. */
28
+ readonly enabled: boolean;
29
+ reportState(report: StateReport): Promise<boolean>;
30
+ reportSession(report: SessionReport): Promise<boolean>;
31
+ reportMetadata(tokens: Readonly<Record<string, string | undefined>>): Promise<boolean>;
32
+ /** Stop accepting reports and drop the ones still waiting. */
33
+ stop(): void;
34
+ /** Wait until the transport has finished everything it took on. */
35
+ settle(): Promise<void>;
36
+ }
37
+ /**
38
+ * Create the client for one pane.
39
+ *
40
+ * Requests are serialized instead of racing: state reports are sequenced
41
+ * server-side, and a queue keeps a session's identity arriving before the state
42
+ * that names it. The queue is bounded in practice because states change a
43
+ * handful of times a turn and each attempt is spent against one deadline.
44
+ */
45
+ export declare function createHerdrClient(env?: HerdrEnvironment, options?: HerdrClientOptions): HerdrClient;
46
+ /**
47
+ * The tokens Herdr will accept, with the ones it cannot hold cleared.
48
+ *
49
+ * An over-long value is not refused: Herdr cuts it at the limit, so a path that
50
+ * was too long would come back shortened and read as another directory. A null
51
+ * is the one value that tells Herdr to forget the token, which is the honest
52
+ * answer for a fact that cannot be represented.
53
+ */
54
+ export declare function acceptedTokens(tokens: Readonly<Record<string, string | undefined>>): Record<string, string | null>;
55
+ /** Herdr's socket is a named pipe on Windows. */
56
+ export declare function socketEndpoint(path: string): string;
57
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/herdr/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAYL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAA;AAEvB,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;AAE3E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAA;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAClD,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACtD,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACtF,8DAA8D;IAC9D,IAAI,IAAI,IAAI,CAAA;IACZ,mEAAmE;IACnE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACxB;AAsBD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,gBAA8B,EAAE,OAAO,GAAE,kBAAuB,GAAG,WAAW,CA4GpH;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAMlH;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}