@sagmans/dsh-tui 0.6.0 → 0.8.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 (271) hide show
  1. package/.agents/skills/dsh-tui-dogfood/SKILL.md +83 -0
  2. package/.agents/skills/dsh-tui-dogfood/references/home-state.md +78 -0
  3. package/.agents/skills/dsh-tui-dogfood/scripts/clone-links.mjs +133 -0
  4. package/.agents/skills/dsh-tui-dogfood/scripts/run-plugin-from-worktree.sh +417 -0
  5. package/.agents/skills/dsh-tui-update-models/SKILL.md +199 -0
  6. package/.agents/skills/dsh-tui-update-models/references/model-wiring.md +292 -0
  7. package/.agents/skills/dsh-tui-update-models/scripts/dump-model-catalog.mjs +314 -0
  8. package/README.md +154 -27
  9. package/lib/agent/present.d.ts.map +1 -1
  10. package/lib/agent/present.js +2 -1
  11. package/lib/agent/present.js.map +1 -1
  12. package/lib/cards/composition.d.ts +68 -0
  13. package/lib/cards/composition.d.ts.map +1 -0
  14. package/lib/cards/composition.js +117 -0
  15. package/lib/cards/composition.js.map +1 -0
  16. package/lib/cards/presenter.d.ts +23 -0
  17. package/lib/cards/presenter.d.ts.map +1 -0
  18. package/lib/cards/presenter.js +394 -0
  19. package/lib/cards/presenter.js.map +1 -0
  20. package/lib/cards/preview.d.ts +42 -0
  21. package/lib/cards/preview.d.ts.map +1 -0
  22. package/lib/cards/preview.js +51 -0
  23. package/lib/cards/preview.js.map +1 -0
  24. package/lib/cards.d.ts +12 -120
  25. package/lib/cards.d.ts.map +1 -1
  26. package/lib/cards.js +4 -556
  27. package/lib/cards.js.map +1 -1
  28. package/lib/compat/section.d.ts +29 -0
  29. package/lib/compat/section.d.ts.map +1 -0
  30. package/lib/compat/section.js +82 -0
  31. package/lib/compat/section.js.map +1 -0
  32. package/lib/config.d.ts +27 -2
  33. package/lib/config.d.ts.map +1 -1
  34. package/lib/config.js +61 -1
  35. package/lib/config.js.map +1 -1
  36. package/lib/contracts.d.ts +28 -0
  37. package/lib/contracts.d.ts.map +1 -1
  38. package/lib/fold-cursor.d.ts +8 -0
  39. package/lib/fold-cursor.d.ts.map +1 -1
  40. package/lib/fold-cursor.js +18 -0
  41. package/lib/fold-cursor.js.map +1 -1
  42. package/lib/gates/question-card.d.ts +77 -0
  43. package/lib/gates/question-card.d.ts.map +1 -0
  44. package/lib/gates/question-card.js +113 -0
  45. package/lib/gates/question-card.js.map +1 -0
  46. package/lib/gates/questions.d.ts +127 -0
  47. package/lib/gates/questions.d.ts.map +1 -0
  48. package/lib/gates/questions.js +418 -0
  49. package/lib/gates/questions.js.map +1 -0
  50. package/lib/gates.d.ts +1 -113
  51. package/lib/gates.d.ts.map +1 -1
  52. package/lib/gates.js +1 -484
  53. package/lib/gates.js.map +1 -1
  54. package/lib/herdr/client.d.ts +8 -0
  55. package/lib/herdr/client.d.ts.map +1 -1
  56. package/lib/herdr/client.js +13 -1
  57. package/lib/herdr/client.js.map +1 -1
  58. package/lib/herdr/constants.d.ts +18 -0
  59. package/lib/herdr/constants.d.ts.map +1 -1
  60. package/lib/herdr/constants.js +18 -0
  61. package/lib/herdr/constants.js.map +1 -1
  62. package/lib/herdr/reporter.d.ts +20 -4
  63. package/lib/herdr/reporter.d.ts.map +1 -1
  64. package/lib/herdr/reporter.js +70 -20
  65. package/lib/herdr/reporter.js.map +1 -1
  66. package/lib/herdr/state.d.ts +10 -0
  67. package/lib/herdr/state.d.ts.map +1 -1
  68. package/lib/herdr/state.js +21 -4
  69. package/lib/herdr/state.js.map +1 -1
  70. package/lib/index.d.ts +1 -0
  71. package/lib/index.d.ts.map +1 -1
  72. package/lib/index.js +348 -2602
  73. package/lib/index.js.map +1 -1
  74. package/lib/input/action-catalog.d.ts +74 -0
  75. package/lib/input/action-catalog.d.ts.map +1 -0
  76. package/lib/input/action-catalog.js +137 -0
  77. package/lib/input/action-catalog.js.map +1 -0
  78. package/lib/input/actions.d.ts +5 -81
  79. package/lib/input/actions.d.ts.map +1 -1
  80. package/lib/input/actions.js +4 -625
  81. package/lib/input/actions.js.map +1 -1
  82. package/lib/input/completion.d.ts +1 -1
  83. package/lib/input/completion.d.ts.map +1 -1
  84. package/lib/input/completion.js +2 -1
  85. package/lib/input/completion.js.map +1 -1
  86. package/lib/input/file-index.d.ts +40 -0
  87. package/lib/input/file-index.d.ts.map +1 -0
  88. package/lib/input/file-index.js +141 -0
  89. package/lib/input/file-index.js.map +1 -0
  90. package/lib/input/file-search.d.ts +1 -38
  91. package/lib/input/file-search.d.ts.map +1 -1
  92. package/lib/input/file-search.js +1 -487
  93. package/lib/input/file-search.js.map +1 -1
  94. package/lib/input/key-press.d.ts +57 -0
  95. package/lib/input/key-press.d.ts.map +1 -0
  96. package/lib/input/key-press.js +218 -0
  97. package/lib/input/key-press.js.map +1 -0
  98. package/lib/input/keymap-conflicts.d.ts +59 -0
  99. package/lib/input/keymap-conflicts.d.ts.map +1 -0
  100. package/lib/input/keymap-conflicts.js +292 -0
  101. package/lib/input/keymap-conflicts.js.map +1 -0
  102. package/lib/input/keymap-settings.js +1 -1
  103. package/lib/input/keymap-settings.js.map +1 -1
  104. package/lib/input/keymap.d.ts.map +1 -1
  105. package/lib/input/keymap.js +3 -1
  106. package/lib/input/keymap.js.map +1 -1
  107. package/lib/input/workspace-files.d.ts +10 -0
  108. package/lib/input/workspace-files.d.ts.map +1 -0
  109. package/lib/input/workspace-files.js +359 -0
  110. package/lib/input/workspace-files.js.map +1 -0
  111. package/lib/install-skills.d.ts +39 -0
  112. package/lib/install-skills.d.ts.map +1 -0
  113. package/lib/install-skills.js +273 -0
  114. package/lib/install-skills.js.map +1 -0
  115. package/lib/keys-command.d.ts +2 -1
  116. package/lib/keys-command.d.ts.map +1 -1
  117. package/lib/keys-command.js +2 -1
  118. package/lib/keys-command.js.map +1 -1
  119. package/lib/model-list.d.ts +37 -0
  120. package/lib/model-list.d.ts.map +1 -0
  121. package/lib/model-list.js +60 -0
  122. package/lib/model-list.js.map +1 -0
  123. package/lib/startup.d.ts +8 -0
  124. package/lib/startup.d.ts.map +1 -1
  125. package/lib/startup.js +120 -24
  126. package/lib/startup.js.map +1 -1
  127. package/lib/subagents.d.ts +7 -3
  128. package/lib/subagents.d.ts.map +1 -1
  129. package/lib/subagents.js +28 -4
  130. package/lib/subagents.js.map +1 -1
  131. package/lib/surface/appearance-preferences.d.ts +26 -0
  132. package/lib/surface/appearance-preferences.d.ts.map +1 -0
  133. package/lib/surface/appearance-preferences.js +139 -0
  134. package/lib/surface/appearance-preferences.js.map +1 -0
  135. package/lib/surface/appearance.d.ts +87 -0
  136. package/lib/surface/appearance.d.ts.map +1 -0
  137. package/lib/surface/appearance.js +353 -0
  138. package/lib/surface/appearance.js.map +1 -0
  139. package/lib/surface/background-work.d.ts +51 -0
  140. package/lib/surface/background-work.d.ts.map +1 -0
  141. package/lib/surface/background-work.js +172 -0
  142. package/lib/surface/background-work.js.map +1 -0
  143. package/lib/surface/commands.d.ts +82 -0
  144. package/lib/surface/commands.d.ts.map +1 -0
  145. package/lib/surface/commands.js +370 -0
  146. package/lib/surface/commands.js.map +1 -0
  147. package/lib/surface/modal-input.d.ts +59 -0
  148. package/lib/surface/modal-input.d.ts.map +1 -0
  149. package/lib/surface/modal-input.js +243 -0
  150. package/lib/surface/modal-input.js.map +1 -0
  151. package/lib/surface/model-choice.d.ts +54 -0
  152. package/lib/surface/model-choice.d.ts.map +1 -0
  153. package/lib/surface/model-choice.js +325 -0
  154. package/lib/surface/model-choice.js.map +1 -0
  155. package/lib/surface/preset-choice.d.ts +78 -0
  156. package/lib/surface/preset-choice.d.ts.map +1 -0
  157. package/lib/surface/preset-choice.js +163 -0
  158. package/lib/surface/preset-choice.js.map +1 -0
  159. package/lib/surface/prompt-input.d.ts +97 -0
  160. package/lib/surface/prompt-input.d.ts.map +1 -0
  161. package/lib/surface/prompt-input.js +215 -0
  162. package/lib/surface/prompt-input.js.map +1 -0
  163. package/lib/surface/prompt-memory.d.ts +76 -0
  164. package/lib/surface/prompt-memory.d.ts.map +1 -0
  165. package/lib/surface/prompt-memory.js +167 -0
  166. package/lib/surface/prompt-memory.js.map +1 -0
  167. package/lib/surface/session-lifecycle.d.ts +120 -0
  168. package/lib/surface/session-lifecycle.d.ts.map +1 -0
  169. package/lib/surface/session-lifecycle.js +324 -0
  170. package/lib/surface/session-lifecycle.js.map +1 -0
  171. package/lib/surface/session-picker.d.ts +39 -0
  172. package/lib/surface/session-picker.d.ts.map +1 -0
  173. package/lib/surface/session-picker.js +107 -0
  174. package/lib/surface/session-picker.js.map +1 -0
  175. package/lib/surface/session-view.d.ts +86 -0
  176. package/lib/surface/session-view.d.ts.map +1 -0
  177. package/lib/surface/session-view.js +215 -0
  178. package/lib/surface/session-view.js.map +1 -0
  179. package/lib/surface/staged-turns.d.ts +81 -0
  180. package/lib/surface/staged-turns.d.ts.map +1 -0
  181. package/lib/surface/staged-turns.js +206 -0
  182. package/lib/surface/staged-turns.js.map +1 -0
  183. package/lib/surface/terminal-lifecycle.d.ts +76 -0
  184. package/lib/surface/terminal-lifecycle.d.ts.map +1 -0
  185. package/lib/surface/terminal-lifecycle.js +222 -0
  186. package/lib/surface/terminal-lifecycle.js.map +1 -0
  187. package/lib/terminal-text/scan.d.ts +44 -0
  188. package/lib/terminal-text/scan.d.ts.map +1 -0
  189. package/lib/terminal-text/scan.js +195 -0
  190. package/lib/terminal-text/scan.js.map +1 -0
  191. package/lib/terminal-text/sgr.d.ts +32 -0
  192. package/lib/terminal-text/sgr.d.ts.map +1 -0
  193. package/lib/terminal-text/sgr.js +203 -0
  194. package/lib/terminal-text/sgr.js.map +1 -0
  195. package/lib/terminal-text.d.ts +1 -1
  196. package/lib/terminal-text.d.ts.map +1 -1
  197. package/lib/terminal-text.js +2 -379
  198. package/lib/terminal-text.js.map +1 -1
  199. package/lib/theme-command.js +2 -1
  200. package/lib/theme-command.js.map +1 -1
  201. package/lib/theme-defaults.d.ts +64 -0
  202. package/lib/theme-defaults.d.ts.map +1 -0
  203. package/lib/theme-defaults.js +248 -0
  204. package/lib/theme-defaults.js.map +1 -0
  205. package/lib/theme-files.d.ts +1 -1
  206. package/lib/theme-files.d.ts.map +1 -1
  207. package/lib/theme-files.js +1 -1
  208. package/lib/theme-files.js.map +1 -1
  209. package/lib/theme-resolver.d.ts +36 -0
  210. package/lib/theme-resolver.d.ts.map +1 -0
  211. package/lib/theme-resolver.js +112 -0
  212. package/lib/theme-resolver.js.map +1 -0
  213. package/lib/theme-schema.d.ts.map +1 -1
  214. package/lib/theme-schema.js +3 -2
  215. package/lib/theme-schema.js.map +1 -1
  216. package/lib/theme-settings.d.ts +5 -7
  217. package/lib/theme-settings.d.ts.map +1 -1
  218. package/lib/theme-settings.js +37 -21
  219. package/lib/theme-settings.js.map +1 -1
  220. package/lib/theme-tokens.d.ts +0 -89
  221. package/lib/theme-tokens.d.ts.map +1 -1
  222. package/lib/theme-tokens.js +0 -356
  223. package/lib/theme-tokens.js.map +1 -1
  224. package/lib/theme.d.ts +1 -1
  225. package/lib/theme.d.ts.map +1 -1
  226. package/lib/theme.js +2 -1
  227. package/lib/theme.js.map +1 -1
  228. package/lib/tool-display.d.ts.map +1 -1
  229. package/lib/tool-display.js +2 -1
  230. package/lib/tool-display.js.map +1 -1
  231. package/lib/transcript/message-content.d.ts +21 -0
  232. package/lib/transcript/message-content.d.ts.map +1 -0
  233. package/lib/transcript/message-content.js +61 -0
  234. package/lib/transcript/message-content.js.map +1 -0
  235. package/lib/transcript/tool-calls.d.ts +106 -0
  236. package/lib/transcript/tool-calls.d.ts.map +1 -0
  237. package/lib/transcript/tool-calls.js +254 -0
  238. package/lib/transcript/tool-calls.js.map +1 -0
  239. package/lib/transcript.d.ts +14 -55
  240. package/lib/transcript.d.ts.map +1 -1
  241. package/lib/transcript.js +31 -253
  242. package/lib/transcript.js.map +1 -1
  243. package/lib/ui/dock.d.ts +14 -2
  244. package/lib/ui/dock.d.ts.map +1 -1
  245. package/lib/ui/dock.js +52 -10
  246. package/lib/ui/dock.js.map +1 -1
  247. package/lib/ui/editor.d.ts.map +1 -1
  248. package/lib/ui/editor.js +2 -1
  249. package/lib/ui/editor.js.map +1 -1
  250. package/lib/ui/keymap-picker.d.ts +2 -1
  251. package/lib/ui/keymap-picker.d.ts.map +1 -1
  252. package/lib/ui/keymap-picker.js +1 -0
  253. package/lib/ui/keymap-picker.js.map +1 -1
  254. package/lib/ui/view/gate-card.d.ts +21 -0
  255. package/lib/ui/view/gate-card.d.ts.map +1 -0
  256. package/lib/ui/view/gate-card.js +104 -0
  257. package/lib/ui/view/gate-card.js.map +1 -0
  258. package/lib/ui/view/tool-card.d.ts +149 -0
  259. package/lib/ui/view/tool-card.d.ts.map +1 -0
  260. package/lib/ui/view/tool-card.js +429 -0
  261. package/lib/ui/view/tool-card.js.map +1 -0
  262. package/lib/ui/view/transcript-message.d.ts +62 -0
  263. package/lib/ui/view/transcript-message.d.ts.map +1 -0
  264. package/lib/ui/view/transcript-message.js +158 -0
  265. package/lib/ui/view/transcript-message.js.map +1 -0
  266. package/lib/ui/view.d.ts +105 -223
  267. package/lib/ui/view.d.ts.map +1 -1
  268. package/lib/ui/view.js +132 -679
  269. package/lib/ui/view.js.map +1 -1
  270. package/package.json +3 -1
  271. package/themes/violet-orbit.yaml +7 -5
@@ -0,0 +1,127 @@
1
+ import { type GateCard, type GateInput, type GateQuestion, type GateAnswer } from '../gates.ts';
2
+ import { type Keymap } from '../input/actions.ts';
3
+ /**
4
+ * Read the seam's request into the gate's own vocabulary.
5
+ *
6
+ * A question without options is answered by typing, which is why it becomes an
7
+ * option-less gate rather than a rejected request: the model asked for text.
8
+ */
9
+ export declare function toGateQuestions(request: unknown): GateQuestion[];
10
+ /** One option with the position it answers for, so filtering can drop rows and keep the meaning. */
11
+ export interface PositionedOption {
12
+ readonly option: GateQuestion['options'][number];
13
+ readonly position: number;
14
+ }
15
+ /**
16
+ * A pending batch of questions.
17
+ *
18
+ * Answers are collected per question and returned in the seam's shape. An
19
+ * escape skips the current question with an empty selection rather than
20
+ * aborting the batch, so a human who cannot answer one question still returns
21
+ * everything else they decided.
22
+ */
23
+ export declare class QuestionGate {
24
+ private readonly questions;
25
+ /** The editor every typed answer is written in, whichever row asks for it. */
26
+ private readonly input;
27
+ /** The keys in force, read per press so a settings edit lands on the next key. */
28
+ private readonly keys;
29
+ private index;
30
+ private cursor;
31
+ private typed;
32
+ /** Whether the cursor is on the free-text row. */
33
+ private atCustom;
34
+ /**
35
+ * The row an escape from the free-text row returns to.
36
+ *
37
+ * It is the row the reader last acted on — walked to, picked by its number, or
38
+ * toggled — because that is the option they were looking at when they decided
39
+ * to answer freely, and it is not always the row the cursor still stands on: a
40
+ * digit picks by number without walking anywhere.
41
+ */
42
+ private customFrom;
43
+ private readonly chosen;
44
+ private readonly custom;
45
+ private finished;
46
+ constructor(questions: readonly GateQuestion[],
47
+ /** The editor every typed answer is written in, whichever row asks for it. */
48
+ input: GateInput,
49
+ /** The keys in force, read per press so a settings edit lands on the next key. */
50
+ keys: () => Keymap);
51
+ /**
52
+ * Empty the editor for the question now under the cursor.
53
+ *
54
+ * The editor belongs to the surface and outlives one question, so an answer
55
+ * must never cross from the last question into the next — or from a gate that
56
+ * was abandoned into the one that follows it. Its mode follows the question
57
+ * for the same reason: a credential must not be shown because the last
58
+ * question was not one.
59
+ */
60
+ private resetInput;
61
+ get resolved(): boolean;
62
+ /**
63
+ * Stop a question whose caller is gone.
64
+ *
65
+ * WHY: an aborted call has no reader for the answer, and a live gate would
66
+ * otherwise keep the keyboard — and the borrowed editor — until someone
67
+ * typed into a call that had already ended.
68
+ */
69
+ cancel(): void;
70
+ private get current();
71
+ /**
72
+ * Options the typed filter leaves, in the order they were listed.
73
+ *
74
+ * The order is not the score order a picker uses: a digit answers by
75
+ * position, and re-ranking rows would move the number the reader just read.
76
+ */
77
+ private matched;
78
+ /**
79
+ * The rows the keys and the card agree on: the filter, then a window around
80
+ * the cursor, because a list as long as a provider catalog would otherwise
81
+ * push the editor off the screen.
82
+ */
83
+ private windowed;
84
+ /** The row under the cursor, as the filter leaves it. */
85
+ private currentRow;
86
+ /** Take or drop one source option, by single-select replacement or multi-select toggle. */
87
+ private pick;
88
+ /**
89
+ * Whether a keystroke is answer text rather than a filter.
90
+ *
91
+ * A question without options has no list to filter, and the free-text row is
92
+ * where a question with options collects an answer the model did not list.
93
+ */
94
+ private typingAnswer;
95
+ /** Add text to the filter, or to the answer the current row collects. */
96
+ private absorb;
97
+ /** Apply one key press; returns the batch answer the first time it completes. */
98
+ handleKey(data: string): GateAnswer[] | undefined;
99
+ /**
100
+ * One key press while the free-text row holds the cursor.
101
+ *
102
+ * Walking back to the list keeps whatever was typed, so a reader who changes
103
+ * their mind about answering freely has not lost the text yet. An escape
104
+ * leaves the row the same way, because a question skipped by accident is a
105
+ * question the reader has to answer again: from the list, where every other
106
+ * question is skipped, an escape skips this one too.
107
+ */
108
+ private handleCustomKey;
109
+ /** Take the answer the reader confirmed, then leave the question. */
110
+ private confirm;
111
+ /**
112
+ * Leave the current question for the next one.
113
+ *
114
+ * Typed text belongs to the question being left, so it never crosses into the
115
+ * next one — which is why a skipped question reports no typed answer at all.
116
+ */
117
+ private advance;
118
+ private result;
119
+ /**
120
+ * The card this gate would draw, assembled as a snapshot for the projector.
121
+ *
122
+ * The window, the filter, and the chosen labels are read here, once, so the
123
+ * projector cannot observe a gate that moved on between two of its reads.
124
+ */
125
+ card(): GateCard;
126
+ }
127
+ //# sourceMappingURL=questions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../../src/gates/questions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAS,KAAK,YAAY,EAAE,KAAK,UAAU,EAAqB,MAAM,aAAa,CAAA;AAGzH,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAQhE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,EAAE,CAyBhE;AAiBD,oGAAoG;AACpG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;;;GAOG;AACH,qBAAa,YAAY;IAoBrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,IAAI;IAvBvB,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,KAAK,CAAK;IAClB,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAQ;IACxB;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAQ;gBAGL,SAAS,EAAE,SAAS,YAAY,EAAE;IACnD,8EAA8E;IAC7D,KAAK,EAAE,SAAS;IACjC,kFAAkF;IACjE,IAAI,EAAE,MAAM,MAAM;IASrC;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAKlB,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;;;OAMG;IACH,MAAM,IAAI,IAAI;IAId,OAAO,KAAK,OAAO,GAElB;IAED;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IAOf;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAOhB,yDAAyD;IACzD,OAAO,CAAC,UAAU;IAKlB,2FAA2F;IAC3F,OAAO,CAAC,IAAI;IAUZ;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB,yEAAyE;IACzE,OAAO,CAAC,MAAM;IAcd,iFAAiF;IACjF,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,SAAS;IAgGjD;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IA0BvB,qEAAqE;IACrE,OAAO,CAAC,OAAO;IAaf;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,MAAM;IAYd;;;;;OAKG;IACH,IAAI,IAAI,QAAQ;CAuCjB"}
@@ -0,0 +1,418 @@
1
+ import { questionCard } from "./question-card.js";
2
+ import { lines, CUSTOM_ROW_NUMBER } from "../gates.js";
3
+ import { CUSTOM_ROW_LABEL, CUSTOM_ROW_DESCRIPTION, CUSTOM_ROW_SHORTHAND, namedKeys, customRowExits, customHint, SECRET_ROW_LABEL, declaresSecret } from "./question-card.js";
4
+ import { matchesKey } from '@earendil-works/pi-tui';
5
+ import { matchesAction } from "../input/actions.js";
6
+ import { pastedText } from "../input.js";
7
+ import { matchScore } from "../input/match.js";
8
+ function asRecord(value) {
9
+ return typeof value === 'object' && value !== null ? value : undefined;
10
+ }
11
+ /**
12
+ * Read the seam's request into the gate's own vocabulary.
13
+ *
14
+ * A question without options is answered by typing, which is why it becomes an
15
+ * option-less gate rather than a rejected request: the model asked for text.
16
+ */
17
+ export function toGateQuestions(request) {
18
+ const record = asRecord(request);
19
+ const raw = Array.isArray(record?.questions) ? record.questions : [];
20
+ const questions = [];
21
+ for (const item of raw) {
22
+ const entry = asRecord(item);
23
+ if (entry === undefined || typeof entry.id !== 'string')
24
+ continue;
25
+ const options = (Array.isArray(entry.options) ? entry.options : []).flatMap(option => {
26
+ const candidate = asRecord(option);
27
+ if (candidate === undefined || typeof candidate.label !== 'string')
28
+ return [];
29
+ return [{
30
+ label: candidate.label,
31
+ description: typeof candidate.description === 'string' ? candidate.description : undefined,
32
+ }];
33
+ });
34
+ questions.push({
35
+ id: entry.id,
36
+ question: typeof entry.question === 'string' ? entry.question : 'question',
37
+ header: typeof entry.header === 'string' ? entry.header : undefined,
38
+ detail: typeof entry.detail === 'string' ? entry.detail : undefined,
39
+ options,
40
+ multiSelect: entry.multiSelect === true,
41
+ });
42
+ }
43
+ return questions;
44
+ }
45
+ /** How many option rows a question shows at once, so a catalog-sized list leaves the editor in view. */
46
+ const QUESTION_WINDOW = 12;
47
+ /**
48
+ * Whether a press leaves the free-text row for the option list.
49
+ *
50
+ * The arrows are the field's own, so they leave whatever the map says, which
51
+ * keeps a reader who moved the question keys from being stranded in the field;
52
+ * the question's own keys follow the map so a rebound alias still works here.
53
+ */
54
+ function leavesCustomRow(map, data) {
55
+ return matchesKey(data, 'up') || matchesKey(data, 'down')
56
+ || matchesAction(map, 'question.up', data) || matchesAction(map, 'question.down', data);
57
+ }
58
+ /**
59
+ * A pending batch of questions.
60
+ *
61
+ * Answers are collected per question and returned in the seam's shape. An
62
+ * escape skips the current question with an empty selection rather than
63
+ * aborting the batch, so a human who cannot answer one question still returns
64
+ * everything else they decided.
65
+ */
66
+ export class QuestionGate {
67
+ questions;
68
+ input;
69
+ keys;
70
+ index = 0;
71
+ cursor = 0;
72
+ typed = '';
73
+ /** Whether the cursor is on the free-text row. */
74
+ atCustom = false;
75
+ /**
76
+ * The row an escape from the free-text row returns to.
77
+ *
78
+ * It is the row the reader last acted on — walked to, picked by its number, or
79
+ * toggled — because that is the option they were looking at when they decided
80
+ * to answer freely, and it is not always the row the cursor still stands on: a
81
+ * digit picks by number without walking anywhere.
82
+ */
83
+ customFrom = 0;
84
+ chosen = [];
85
+ custom = [];
86
+ finished = false;
87
+ constructor(questions,
88
+ /** The editor every typed answer is written in, whichever row asks for it. */
89
+ input,
90
+ /** The keys in force, read per press so a settings edit lands on the next key. */
91
+ keys) {
92
+ this.questions = questions;
93
+ this.input = input;
94
+ this.keys = keys;
95
+ for (const _ of questions) {
96
+ this.chosen.push([]);
97
+ this.custom.push(undefined);
98
+ }
99
+ this.resetInput();
100
+ }
101
+ /**
102
+ * Empty the editor for the question now under the cursor.
103
+ *
104
+ * The editor belongs to the surface and outlives one question, so an answer
105
+ * must never cross from the last question into the next — or from a gate that
106
+ * was abandoned into the one that follows it. Its mode follows the question
107
+ * for the same reason: a credential must not be shown because the last
108
+ * question was not one.
109
+ */
110
+ resetInput() {
111
+ this.input.setText('');
112
+ this.input.setMode?.(this.current !== undefined && declaresSecret(this.current.id) ? 'secret' : 'answer');
113
+ }
114
+ get resolved() {
115
+ return this.finished;
116
+ }
117
+ /**
118
+ * Stop a question whose caller is gone.
119
+ *
120
+ * WHY: an aborted call has no reader for the answer, and a live gate would
121
+ * otherwise keep the keyboard — and the borrowed editor — until someone
122
+ * typed into a call that had already ended.
123
+ */
124
+ cancel() {
125
+ this.finished = true;
126
+ }
127
+ get current() {
128
+ return this.questions[this.index];
129
+ }
130
+ /**
131
+ * Options the typed filter leaves, in the order they were listed.
132
+ *
133
+ * The order is not the score order a picker uses: a digit answers by
134
+ * position, and re-ranking rows would move the number the reader just read.
135
+ */
136
+ matched(question) {
137
+ const needle = this.typed.trim();
138
+ return question.options
139
+ .map((option, position) => ({ option, position }))
140
+ .filter(({ option }) => matchScore(needle, `${option.label} ${option.description ?? ''}`) !== undefined);
141
+ }
142
+ /**
143
+ * The rows the keys and the card agree on: the filter, then a window around
144
+ * the cursor, because a list as long as a provider catalog would otherwise
145
+ * push the editor off the screen.
146
+ */
147
+ windowed(question) {
148
+ const matched = this.matched(question);
149
+ const cursor = Math.min(this.cursor, Math.max(0, matched.length - 1));
150
+ const start = Math.max(0, Math.min(cursor - Math.floor(QUESTION_WINDOW / 2), matched.length - QUESTION_WINDOW));
151
+ return { rows: matched.slice(start, start + QUESTION_WINDOW), start, cursor };
152
+ }
153
+ /** The row under the cursor, as the filter leaves it. */
154
+ currentRow(question) {
155
+ const matched = this.matched(question);
156
+ return matched[Math.min(this.cursor, Math.max(0, matched.length - 1))];
157
+ }
158
+ /** Take or drop one source option, by single-select replacement or multi-select toggle. */
159
+ pick(position) {
160
+ const question = this.current;
161
+ const option = question?.options[position];
162
+ if (question === undefined || option === undefined)
163
+ return;
164
+ const chosen = this.chosen[this.index] ?? [];
165
+ this.chosen[this.index] = chosen.includes(option.label)
166
+ ? chosen.filter(label => label !== option.label)
167
+ : question.multiSelect === true ? [...chosen, option.label] : [option.label];
168
+ }
169
+ /**
170
+ * Whether a keystroke is answer text rather than a filter.
171
+ *
172
+ * A question without options has no list to filter, and the free-text row is
173
+ * where a question with options collects an answer the model did not list.
174
+ */
175
+ typingAnswer(question) {
176
+ return question.options.length === 0 || this.atCustom;
177
+ }
178
+ /** Add text to the filter, or to the answer the current row collects. */
179
+ absorb(text) {
180
+ const question = this.current;
181
+ if (question === undefined || text === '')
182
+ return;
183
+ if (this.typingAnswer(question)) {
184
+ // The editor decides what an insertion is: a paste arrives as one edit,
185
+ // and a multi-character chunk is one undo step rather than many.
186
+ this.input.handleInput(text);
187
+ return;
188
+ }
189
+ this.typed += text;
190
+ this.cursor = 0;
191
+ this.customFrom = 0;
192
+ }
193
+ /** Apply one key press; returns the batch answer the first time it completes. */
194
+ handleKey(data) {
195
+ const question = this.current;
196
+ if (this.finished || question === undefined)
197
+ return undefined;
198
+ const paste = pastedText(data);
199
+ if (paste !== undefined) {
200
+ // An answer takes the paste sequence itself, because the editor reads it;
201
+ // a filter takes the text inside it, because nothing else would.
202
+ this.absorb(this.typingAnswer(question) ? data : paste);
203
+ return undefined;
204
+ }
205
+ // Abandoning the batch is the one decision that belongs to no row: the
206
+ // reader asked to be out of the questions, and the row the cursor happens
207
+ // to sit on is not an answer to that. It settles the way an aborted call
208
+ // does, with no answers at all, so a partial batch is never handed over as
209
+ // if the reader had walked through it.
210
+ if (matchesAction(this.keys(), 'question.cancel', data)) {
211
+ this.cancel();
212
+ return [];
213
+ }
214
+ // The free-text row is a text field, so the keys that walk or pick a list
215
+ // would otherwise take the very characters an answer is made of.
216
+ if (this.atCustom)
217
+ return this.handleCustomKey(data);
218
+ const matched = this.matched(question);
219
+ const keys = this.keys();
220
+ if (matchesAction(keys, 'question.up', data)) {
221
+ this.cursor = Math.max(0, this.cursor - 1);
222
+ this.customFrom = this.cursor;
223
+ return undefined;
224
+ }
225
+ if (matchesAction(keys, 'question.down', data)) {
226
+ // Below the last option sits the free-text row, which is the second way
227
+ // to reach it; a list with nothing left to show steps straight onto it.
228
+ if (this.cursor >= matched.length - 1) {
229
+ this.atCustom = true;
230
+ }
231
+ else {
232
+ this.cursor += 1;
233
+ this.customFrom = this.cursor;
234
+ }
235
+ return undefined;
236
+ }
237
+ if (question.options.length > 0 && matchesAction(keys, 'question.toggle', data)) {
238
+ const row = this.currentRow(question);
239
+ if (row !== undefined)
240
+ this.pick(row.position);
241
+ this.customFrom = this.cursor;
242
+ return undefined;
243
+ }
244
+ if (matchesAction(keys, 'question.skip', data)) {
245
+ this.advance();
246
+ return this.result();
247
+ }
248
+ if (matchesAction(keys, 'question.confirm', data)) {
249
+ const chosen = this.chosen[this.index] ?? [];
250
+ if (question.options.length > 0 && chosen.length === 0) {
251
+ // A reader who typed enough to narrow the list is naming the row it
252
+ // left under the cursor; one who typed an id the list does not hold is
253
+ // naming that instead, which is why the typed text becomes the answer.
254
+ const row = this.currentRow(question);
255
+ if (row !== undefined)
256
+ this.pick(row.position);
257
+ else if (this.typed.trim() !== '')
258
+ this.custom[this.index] = this.typed.trim();
259
+ }
260
+ this.confirm();
261
+ return this.result();
262
+ }
263
+ if (matchesKey(data, 'backspace')) {
264
+ // The same routing typing follows: a question without options has no
265
+ // filter to erase, and the delete belongs to the answer it collected.
266
+ if (this.typingAnswer(question)) {
267
+ this.input.handleInput(data);
268
+ return undefined;
269
+ }
270
+ this.typed = this.typed.slice(0, -1);
271
+ this.cursor = 0;
272
+ return undefined;
273
+ }
274
+ if (matchesKey(data, 'space')) {
275
+ this.absorb(' ');
276
+ return undefined;
277
+ }
278
+ if (question.options.length > 0 && /^[0-9]$/u.test(data)) {
279
+ const digit = Number.parseInt(data, 10);
280
+ if (digit === CUSTOM_ROW_NUMBER) {
281
+ this.atCustom = true;
282
+ return undefined;
283
+ }
284
+ const row = matched[digit - 1];
285
+ if (row !== undefined) {
286
+ this.pick(row.position);
287
+ this.customFrom = digit - 1;
288
+ }
289
+ return undefined;
290
+ }
291
+ if (data.length === 1 && data >= ' ')
292
+ this.absorb(data);
293
+ return undefined;
294
+ }
295
+ /**
296
+ * One key press while the free-text row holds the cursor.
297
+ *
298
+ * Walking back to the list keeps whatever was typed, so a reader who changes
299
+ * their mind about answering freely has not lost the text yet. An escape
300
+ * leaves the row the same way, because a question skipped by accident is a
301
+ * question the reader has to answer again: from the list, where every other
302
+ * question is skipped, an escape skips this one too.
303
+ */
304
+ handleCustomKey(data) {
305
+ if (matchesAction(this.keys(), 'question.confirm', data)) {
306
+ this.confirm();
307
+ return this.result();
308
+ }
309
+ // The keys that leave a text field are the field's own, not the question's:
310
+ // a skip the reader moved elsewhere must not quietly mean "walk back". The
311
+ // rows the question does own still work here, and the hint names both
312
+ // (customRowExits).
313
+ if (leavesCustomRow(this.keys(), data)) {
314
+ this.atCustom = false;
315
+ return undefined;
316
+ }
317
+ if (matchesKey(data, 'escape')) {
318
+ const question = this.current;
319
+ const rows = question === undefined ? 0 : this.matched(question).length;
320
+ this.atCustom = false;
321
+ this.cursor = Math.min(this.customFrom, Math.max(0, rows - 1));
322
+ return undefined;
323
+ }
324
+ // Anything else is the editor's: movement, deletion, undo, and the keys
325
+ // that insert a character this gate has no business knowing about.
326
+ this.input.handleInput(data);
327
+ return undefined;
328
+ }
329
+ /** Take the answer the reader confirmed, then leave the question. */
330
+ confirm() {
331
+ const question = this.current;
332
+ if (question === undefined)
333
+ return;
334
+ const text = this.input.getExpandedText().trim();
335
+ if (text !== '') {
336
+ this.custom[this.index] = text;
337
+ // The seam reads a single-select custom as the answer itself, so a label
338
+ // picked before it would be a second answer the caller has to reconcile.
339
+ if (question.multiSelect !== true)
340
+ this.chosen[this.index] = [];
341
+ }
342
+ this.advance();
343
+ }
344
+ /**
345
+ * Leave the current question for the next one.
346
+ *
347
+ * Typed text belongs to the question being left, so it never crosses into the
348
+ * next one — which is why a skipped question reports no typed answer at all.
349
+ */
350
+ advance() {
351
+ this.typed = '';
352
+ this.atCustom = false;
353
+ this.customFrom = 0;
354
+ this.cursor = 0;
355
+ this.index += 1;
356
+ if (this.index >= this.questions.length)
357
+ this.finished = true;
358
+ this.resetInput();
359
+ }
360
+ result() {
361
+ if (!this.finished)
362
+ return undefined;
363
+ return this.questions.map((question, position) => {
364
+ const custom = this.custom[position];
365
+ return {
366
+ id: question.id,
367
+ selected: this.chosen[position] ?? [],
368
+ ...(custom === undefined ? {} : { custom }),
369
+ };
370
+ });
371
+ }
372
+ /**
373
+ * The card this gate would draw, assembled as a snapshot for the projector.
374
+ *
375
+ * The window, the filter, and the chosen labels are read here, once, so the
376
+ * projector cannot observe a gate that moved on between two of its reads.
377
+ */
378
+ card() {
379
+ const question = this.current;
380
+ if (question === undefined) {
381
+ return questionCard({
382
+ question: undefined,
383
+ position: this.index + 1,
384
+ total: this.questions.length,
385
+ chosen: [],
386
+ typed: '',
387
+ atCustom: false,
388
+ written: false,
389
+ matched: [],
390
+ rows: [],
391
+ start: 0,
392
+ cursor: 0,
393
+ keys: this.keys(),
394
+ input: this.input,
395
+ });
396
+ }
397
+ const matched = this.matched(question);
398
+ const { rows, start, cursor } = this.windowed(question);
399
+ return questionCard({
400
+ question,
401
+ position: this.index + 1,
402
+ total: this.questions.length,
403
+ chosen: this.chosen[this.index] ?? [],
404
+ typed: this.typed,
405
+ atCustom: this.atCustom,
406
+ // The editor holds the answer, so whether one has been written is its own
407
+ // answer to give; the card only decides where to draw it.
408
+ written: this.input.getExpandedText() !== '',
409
+ matched,
410
+ rows,
411
+ start,
412
+ cursor,
413
+ keys: this.keys(),
414
+ input: this.input,
415
+ });
416
+ }
417
+ }
418
+ //# sourceMappingURL=questions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.js","sourceRoot":"","sources":["../../src/gates/questions.ts"],"names":[],"mappings":"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"}