@sagmans/dsh-tui 0.1.2 → 0.3.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 (158) hide show
  1. package/README.md +196 -17
  2. package/cordis.patch.yml +4 -2
  3. package/lib/agent/host.d.ts +14 -0
  4. package/lib/agent/host.d.ts.map +1 -1
  5. package/lib/agent/host.js +20 -4
  6. package/lib/agent/host.js.map +1 -1
  7. package/lib/agent/model.d.ts +50 -0
  8. package/lib/agent/model.d.ts.map +1 -1
  9. package/lib/agent/model.js +87 -1
  10. package/lib/agent/model.js.map +1 -1
  11. package/lib/agent/present.d.ts +7 -1
  12. package/lib/agent/present.d.ts.map +1 -1
  13. package/lib/agent/present.js +33 -4
  14. package/lib/agent/present.js.map +1 -1
  15. package/lib/agent/presets.d.ts +7 -1
  16. package/lib/agent/presets.d.ts.map +1 -1
  17. package/lib/agent/presets.js +7 -3
  18. package/lib/agent/presets.js.map +1 -1
  19. package/lib/agent/status.d.ts +10 -0
  20. package/lib/agent/status.d.ts.map +1 -1
  21. package/lib/agent/status.js +2 -0
  22. package/lib/agent/status.js.map +1 -1
  23. package/lib/cards.d.ts +127 -7
  24. package/lib/cards.d.ts.map +1 -1
  25. package/lib/cards.js +381 -52
  26. package/lib/cards.js.map +1 -1
  27. package/lib/export.d.ts +5 -4
  28. package/lib/export.d.ts.map +1 -1
  29. package/lib/export.js +62 -13
  30. package/lib/export.js.map +1 -1
  31. package/lib/fold-cursor.d.ts +23 -0
  32. package/lib/fold-cursor.d.ts.map +1 -0
  33. package/lib/fold-cursor.js +31 -0
  34. package/lib/fold-cursor.js.map +1 -0
  35. package/lib/gates.d.ts +145 -2
  36. package/lib/gates.d.ts.map +1 -1
  37. package/lib/gates.js +335 -40
  38. package/lib/gates.js.map +1 -1
  39. package/lib/index.d.ts +7 -1
  40. package/lib/index.d.ts.map +1 -1
  41. package/lib/index.js +651 -92
  42. package/lib/index.js.map +1 -1
  43. package/lib/input/actions.d.ts +136 -0
  44. package/lib/input/actions.d.ts.map +1 -0
  45. package/lib/input/actions.js +740 -0
  46. package/lib/input/actions.js.map +1 -0
  47. package/lib/input/keymap-settings.d.ts +21 -0
  48. package/lib/input/keymap-settings.d.ts.map +1 -0
  49. package/lib/input/keymap-settings.js +28 -0
  50. package/lib/input/keymap-settings.js.map +1 -0
  51. package/lib/input/keymap.d.ts +91 -0
  52. package/lib/input/keymap.d.ts.map +1 -0
  53. package/lib/input/keymap.js +170 -0
  54. package/lib/input/keymap.js.map +1 -0
  55. package/lib/input/match.d.ts +10 -0
  56. package/lib/input/match.d.ts.map +1 -0
  57. package/lib/input/match.js +83 -0
  58. package/lib/input/match.js.map +1 -0
  59. package/lib/input/submission.d.ts +8 -1
  60. package/lib/input/submission.d.ts.map +1 -1
  61. package/lib/input/submission.js +9 -2
  62. package/lib/input/submission.js.map +1 -1
  63. package/lib/input.d.ts +17 -0
  64. package/lib/input.d.ts.map +1 -0
  65. package/lib/input.js +27 -0
  66. package/lib/input.js.map +1 -0
  67. package/lib/keys-command.d.ts +16 -0
  68. package/lib/keys-command.d.ts.map +1 -0
  69. package/lib/keys-command.js +60 -0
  70. package/lib/keys-command.js.map +1 -0
  71. package/lib/queue.d.ts +6 -0
  72. package/lib/queue.d.ts.map +1 -0
  73. package/lib/queue.js +68 -0
  74. package/lib/queue.js.map +1 -0
  75. package/lib/settings-notice.d.ts +19 -0
  76. package/lib/settings-notice.d.ts.map +1 -0
  77. package/lib/settings-notice.js +30 -0
  78. package/lib/settings-notice.js.map +1 -0
  79. package/lib/terminal/warning-screen.d.ts +8 -0
  80. package/lib/terminal/warning-screen.d.ts.map +1 -0
  81. package/lib/terminal/warning-screen.js +66 -0
  82. package/lib/terminal/warning-screen.js.map +1 -0
  83. package/lib/theme-capability.d.ts +36 -0
  84. package/lib/theme-capability.d.ts.map +1 -0
  85. package/lib/theme-capability.js +190 -0
  86. package/lib/theme-capability.js.map +1 -0
  87. package/lib/theme-command.d.ts +10 -0
  88. package/lib/theme-command.d.ts.map +1 -0
  89. package/lib/theme-command.js +61 -0
  90. package/lib/theme-command.js.map +1 -0
  91. package/lib/theme-settings.d.ts +196 -0
  92. package/lib/theme-settings.d.ts.map +1 -0
  93. package/lib/theme-settings.js +229 -0
  94. package/lib/theme-settings.js.map +1 -0
  95. package/lib/theme-tokens.d.ts +110 -0
  96. package/lib/theme-tokens.d.ts.map +1 -0
  97. package/lib/theme-tokens.js +427 -0
  98. package/lib/theme-tokens.js.map +1 -0
  99. package/lib/theme.d.ts +32 -35
  100. package/lib/theme.d.ts.map +1 -1
  101. package/lib/theme.js +112 -63
  102. package/lib/theme.js.map +1 -1
  103. package/lib/tokens.d.ts +15 -0
  104. package/lib/tokens.d.ts.map +1 -0
  105. package/lib/tokens.js +29 -0
  106. package/lib/tokens.js.map +1 -0
  107. package/lib/transcript.d.ts +26 -1
  108. package/lib/transcript.d.ts.map +1 -1
  109. package/lib/transcript.js +153 -25
  110. package/lib/transcript.js.map +1 -1
  111. package/lib/ui/dock.d.ts.map +1 -1
  112. package/lib/ui/dock.js +67 -28
  113. package/lib/ui/dock.js.map +1 -1
  114. package/lib/ui/editor.d.ts +51 -0
  115. package/lib/ui/editor.d.ts.map +1 -0
  116. package/lib/ui/editor.js +159 -0
  117. package/lib/ui/editor.js.map +1 -0
  118. package/lib/ui/frame.d.ts +54 -0
  119. package/lib/ui/frame.d.ts.map +1 -0
  120. package/lib/ui/frame.js +79 -0
  121. package/lib/ui/frame.js.map +1 -0
  122. package/lib/ui/gate-input.d.ts +20 -0
  123. package/lib/ui/gate-input.d.ts.map +1 -0
  124. package/lib/ui/gate-input.js +96 -0
  125. package/lib/ui/gate-input.js.map +1 -0
  126. package/lib/ui/markdown.d.ts +19 -2
  127. package/lib/ui/markdown.d.ts.map +1 -1
  128. package/lib/ui/markdown.js +37 -6
  129. package/lib/ui/markdown.js.map +1 -1
  130. package/lib/ui/mermaid.d.ts +44 -0
  131. package/lib/ui/mermaid.d.ts.map +1 -0
  132. package/lib/ui/mermaid.js +178 -0
  133. package/lib/ui/mermaid.js.map +1 -0
  134. package/lib/ui/picker.d.ts +66 -7
  135. package/lib/ui/picker.d.ts.map +1 -1
  136. package/lib/ui/picker.js +112 -19
  137. package/lib/ui/picker.js.map +1 -1
  138. package/lib/ui/prompt.d.ts +30 -0
  139. package/lib/ui/prompt.d.ts.map +1 -0
  140. package/lib/ui/prompt.js +45 -0
  141. package/lib/ui/prompt.js.map +1 -0
  142. package/lib/ui/queue.d.ts +24 -0
  143. package/lib/ui/queue.d.ts.map +1 -0
  144. package/lib/ui/queue.js +57 -0
  145. package/lib/ui/queue.js.map +1 -0
  146. package/lib/ui/status.d.ts +7 -1
  147. package/lib/ui/status.d.ts.map +1 -1
  148. package/lib/ui/status.js +84 -24
  149. package/lib/ui/status.js.map +1 -1
  150. package/lib/ui/view.d.ts +65 -2
  151. package/lib/ui/view.d.ts.map +1 -1
  152. package/lib/ui/view.js +319 -59
  153. package/lib/ui/view.js.map +1 -1
  154. package/lib/work.d.ts +48 -0
  155. package/lib/work.d.ts.map +1 -1
  156. package/lib/work.js +44 -0
  157. package/lib/work.js.map +1 -1
  158. package/package.json +5 -2
@@ -0,0 +1,178 @@
1
+ import { Marked, visibleWidth } from '@earendil-works/pi-tui';
2
+ import { render } from 'lovely-mermaid';
3
+ /** The one fence language that asks for a drawing. */
4
+ const MERMAID_FENCE_LANG = 'mermaid';
5
+ /** The cheap guard before lexing; case-insensitive because a fence may shout. */
6
+ const MERMAID_MENTION = /mermaid/iu;
7
+ /** Drawings kept before the oldest is laid out again; a streaming reply redraws per delta. */
8
+ export const MERMAID_CACHE_LIMIT = 32;
9
+ /**
10
+ * The largest source this surface lays out.
11
+ *
12
+ * Layout is synchronous and happens inside a frame, and a streaming reply asks
13
+ * for it again on every delta, so past this the frame costs more than the
14
+ * drawing is worth and the source stays. Well above what the renderer's own
15
+ * node cap can fill, so no drawing a reader actually sees is kept out.
16
+ */
17
+ export const MERMAID_MAX_SOURCE = 32 * 1024;
18
+ /** What ends a row without starting a paragraph; two trailing spaces are CommonMark's hard break. */
19
+ const HARD_BREAK = ' \n';
20
+ /** An empty code span has no height, so a blank row stands on a non-breaking space. */
21
+ const BLANK_ROW = '\u00a0';
22
+ const WARNING_LEAD = 'Mermaid diagram not rendered: ';
23
+ const WARNING_MORE = ' (+';
24
+ /** A backtick run inside a row needs a longer delimiter, and a row may hold one inside a label. */
25
+ const BACKTICK_RUN = /`+/gu;
26
+ /**
27
+ * Which element each run of a drawing is, as the token that draws it.
28
+ *
29
+ * The renderer reports what a run *is* and never a colour, so this table is the
30
+ * only place that relates a diagram to the theme; everything else works with
31
+ * roles. Author-assigned classes are deliberately not consulted: a reader's
32
+ * theme is the surface's, not the diagram's.
33
+ */
34
+ const ROLE_TOKEN = {
35
+ border: 'markdown.diagram.border',
36
+ text: 'markdown.diagram.text',
37
+ edge: 'markdown.diagram.edge',
38
+ edgeLabel: 'markdown.diagram.edgeLabel',
39
+ title: 'markdown.diagram.title',
40
+ };
41
+ function isMermaidFence(token) {
42
+ // The info string may carry more than the language, and a fence may shout.
43
+ return token.type === 'code' && token.lang?.trim().split(/\s+/, 1)[0]?.toLowerCase() === MERMAID_FENCE_LANG;
44
+ }
45
+ /** One drawing row as the code span that keeps its spacing. */
46
+ function codeSpan(row) {
47
+ const content = row === '' ? BLANK_ROW : row;
48
+ let longest = 0;
49
+ // Iterated, not spread: a row can carry more runs than a call holds arguments.
50
+ for (const run of content.matchAll(BACKTICK_RUN)) {
51
+ if (run[0].length > longest)
52
+ longest = run[0].length;
53
+ }
54
+ const fence = '`'.repeat(longest + 1);
55
+ // A row that starts or ends with a backtick would otherwise be read as the delimiter itself.
56
+ const padding = content.startsWith('`') || content.endsWith('`') ? ' ' : '';
57
+ return `${fence}${padding}${content}${padding}${fence}`;
58
+ }
59
+ /**
60
+ * The columns a drawing really occupies.
61
+ *
62
+ * The renderer measures with its own tables, and they are not always the
63
+ * terminal's: a halfwidth kana plus a combining mark counts one column there
64
+ * and two on screen. The rows are what the reader gets, so the rows decide.
65
+ */
66
+ function drawnWidth(art) {
67
+ let widest = 0;
68
+ for (const row of art.plain) {
69
+ const columns = visibleWidth(row);
70
+ if (columns > widest)
71
+ widest = columns;
72
+ }
73
+ return widest;
74
+ }
75
+ function warningText(art) {
76
+ const first = art.warnings[0] ?? '';
77
+ const rest = art.warnings.length - 1;
78
+ return `${WARNING_LEAD}${first}${rest > 0 ? `${WARNING_MORE}${rest} more)` : ''}`;
79
+ }
80
+ /**
81
+ * Lay out each distinct source once.
82
+ *
83
+ * A streaming reply asks for the same fences again on every delta, and laying
84
+ * out a diagram is the expensive half of drawing it; the other half is styling
85
+ * runs, which stays per call so a theme swap needs no invalidation.
86
+ */
87
+ function artCache() {
88
+ const drawn = new Map();
89
+ return source => {
90
+ if (drawn.has(source))
91
+ return drawn.get(source) ?? null;
92
+ const art = render(source);
93
+ if (drawn.size >= MERMAID_CACHE_LIMIT) {
94
+ const oldest = drawn.keys().next();
95
+ if (oldest.done !== true)
96
+ drawn.delete(oldest.value);
97
+ }
98
+ drawn.set(source, art);
99
+ return art;
100
+ };
101
+ }
102
+ /**
103
+ * Draw a reply's mermaid fences as terminal art.
104
+ *
105
+ * Replacements are spliced into the message at the offsets the lexer reported,
106
+ * never rebuilt from the tokens: lexing can decide something is not worth a
107
+ * token — a duplicate reference definition, for one — and a message that merely
108
+ * mentions mermaid would then change under a reader who asked for nothing. Text
109
+ * the transform does not draw is copied through byte for byte.
110
+ *
111
+ * A fence is replaced before the markdown is parsed, because that is the only
112
+ * moment the source is still whole: once tokens are flowing the drawing's rows
113
+ * would be re-wrapped as prose and lose the spacing they are made of. Each row
114
+ * is therefore emitted as an inline code span, which the markdown renderer
115
+ * keeps verbatim, and rows are separated by hard breaks so a diagram survives
116
+ * as one block instead of one paragraph.
117
+ */
118
+ export function createMermaidTransform(options) {
119
+ const parser = new Marked();
120
+ const draw = artCache();
121
+ /**
122
+ * The block a body becomes, held apart from the text on either side.
123
+ *
124
+ * Once drawn, the rows are a paragraph, so a blank line on each side is what
125
+ * stops them joining the prose before them or turning a `---` after them into
126
+ * a heading underline. Source that was not drawn is already a block of its own
127
+ * and is left exactly as written.
128
+ */
129
+ function isolated(body, before, after) {
130
+ const lead = before === '' || before.endsWith('\n\n') ? '' : '\n';
131
+ return `${lead}${body}${after === '' ? '\n' : '\n\n'}`;
132
+ }
133
+ /** What one fence becomes: art, or its source with the reason it stayed source. */
134
+ function fenceBlock(token, before, after, availableWidth, live) {
135
+ if (token.text.length > MERMAID_MAX_SOURCE)
136
+ return token.raw;
137
+ const art = draw(token.text);
138
+ // A settled drawing that lost part of its source is worth reporting whether
139
+ // or not it would have fit, because the reader is looking at the source.
140
+ if (!live && art !== null && art.warnings.length > 0) {
141
+ const reason = options.theme.style('markdown.diagram.warning', warningText(art));
142
+ return isolated(`${token.raw}\n${codeSpan(reason)}`, before, after);
143
+ }
144
+ if (art === null || drawnWidth(art) > availableWidth)
145
+ return token.raw;
146
+ const rows = art.styled.map(row => row
147
+ .map(span => (span.role === 'none' ? span.text : options.theme.style(ROLE_TOKEN[span.role], span.text)))
148
+ .join(''));
149
+ return isolated(rows.map(codeSpan).join(HARD_BREAK), before, after);
150
+ }
151
+ return (markdown, availableWidth, live) => {
152
+ const mode = options.mode();
153
+ // A reply that is still arriving is only drawn in streaming mode; the other
154
+ // modes wait for the settled text, which is also the only text whose losses
155
+ // are worth reporting.
156
+ if (mode === 'off' || (live && mode !== 'streaming'))
157
+ return markdown;
158
+ // Lexing is the cost this guard avoids: no fence can be present without the word.
159
+ if (!MERMAID_MENTION.test(markdown))
160
+ return markdown;
161
+ let out = '';
162
+ let cursor = 0;
163
+ for (const token of parser.lexer(markdown)) {
164
+ const at = markdown.indexOf(token.raw, cursor);
165
+ // A lexer that rewrote its own input cannot be spliced back into it, and
166
+ // the message is worth more than the drawing: it stays as written.
167
+ if (at < 0)
168
+ return markdown;
169
+ const body = isMermaidFence(token)
170
+ ? fenceBlock(token, out, markdown.slice(at + token.raw.length), availableWidth, live)
171
+ : token.raw;
172
+ out += markdown.slice(cursor, at) + body;
173
+ cursor = at + token.raw.length;
174
+ }
175
+ return out + markdown.slice(cursor);
176
+ };
177
+ }
178
+ //# sourceMappingURL=mermaid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../../src/ui/mermaid.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
+ import { type Keymap } from '../input/actions.ts';
1
2
  import type { StoredSession } from '../agent/history.ts';
3
+ import { type ModelChoice, type ModelRoute } from '../agent/model.ts';
2
4
  import { type PresetSummary } from '../agent/presets.ts';
3
5
  /** One selectable row of the picker. */
4
6
  export interface PickerRow {
@@ -34,10 +36,15 @@ export type PickerAction = {
34
36
  * window stays around the cursor instead, and the counts say what is hidden.
35
37
  */
36
38
  export declare const PICKER_WINDOW = 12;
37
- /** The hint lines a list uses when it is empty and when it holds rows. */
39
+ /**
40
+ * The hint lines a list uses when it is empty and when it holds rows.
41
+ *
42
+ * Read at paint time rather than built once, because a settings edit while the
43
+ * list is open moves the keys the hint names.
44
+ */
38
45
  export interface PickerHints {
39
- readonly empty: string;
40
- readonly listed: string;
46
+ readonly empty: () => string;
47
+ readonly listed: () => string;
41
48
  }
42
49
  /** Human age of a session, so a list of ids becomes a list of moments. */
43
50
  export declare function describeAge(createdAt: number, now: number): string;
@@ -59,6 +66,8 @@ export declare class ListPicker<Row> {
59
66
  /** Extra text the filter matches besides the row's own label. */
60
67
  private readonly haystackOf;
61
68
  private readonly hints;
69
+ /** The keys in force, read per press so a settings edit lands on the next key. */
70
+ private readonly keys;
62
71
  private cursor;
63
72
  private filter;
64
73
  private note;
@@ -66,8 +75,10 @@ export declare class ListPicker<Row> {
66
75
  /** The value a pick settles on. */
67
76
  idOf: (row: Row) => string, describe: (row: Row) => PickerRow,
68
77
  /** Extra text the filter matches besides the row's own label. */
69
- haystackOf: (row: Row) => string, hints: PickerHints);
70
- /** Rows matching the typed filter, in the order they were listed. */
78
+ haystackOf: (row: Row) => string, hints: PickerHints,
79
+ /** The keys in force, read per press so a settings edit lands on the next key. */
80
+ keys: () => Keymap);
81
+ /** Rows matching the typed filter, best match first. */
71
82
  visible(): readonly Row[];
72
83
  /**
73
84
  * Say why the row under the cursor cannot be taken.
@@ -89,7 +100,7 @@ export declare class ListPicker<Row> {
89
100
  * first paint would make opening the picker as slow as the slowest session.
90
101
  */
91
102
  export declare class SessionPicker extends ListPicker<StoredSession> {
92
- constructor(sessions: readonly StoredSession[], titles: () => ReadonlyMap<string, string>, now?: () => number);
103
+ constructor(sessions: readonly StoredSession[], titles: () => ReadonlyMap<string, string>, now: (() => number) | undefined, keys: () => Keymap);
93
104
  }
94
105
  /**
95
106
  * One agent preset chosen by key press.
@@ -98,6 +109,54 @@ export declare class SessionPicker extends ListPicker<StoredSession> {
98
109
  * the picker is open is present or gone without reopening it.
99
110
  */
100
111
  export declare class PresetPicker extends ListPicker<PresetSummary> {
101
- constructor(presets: () => readonly PresetSummary[], currentId: () => string | undefined);
112
+ constructor(presets: () => readonly PresetSummary[], currentId: () => string | undefined, keys: () => Keymap);
113
+ }
114
+ /**
115
+ * One configured model route chosen by key press.
116
+ *
117
+ * Rows are the caller's and are re-read on every key and paint, so a provider
118
+ * whose model list arrives after the picker opened appears in it without
119
+ * reopening, and the filter the reader already typed applies to those late
120
+ * rows too.
121
+ */
122
+ export declare class ModelPicker extends ListPicker<ModelRoute> {
123
+ constructor(routes: () => readonly ModelRoute[], current: () => ModelChoice | undefined, keys: () => Keymap);
124
+ }
125
+ /**
126
+ * The pick id that clears an explicit effort.
127
+ *
128
+ * An absent effort is a real choice — it restores the model's own default — so
129
+ * it needs an id, and no adapter-owned effort may be empty.
130
+ */
131
+ export declare const PROVIDER_DEFAULT_EFFORT_ID = "";
132
+ /** One reasoning level a route offers, as the picker shows it. */
133
+ export interface EffortChoice {
134
+ readonly id: string;
135
+ readonly name: string;
136
+ readonly description?: string;
137
+ /** Whether this is the effort in force, which the row says in words. */
138
+ readonly current: boolean;
139
+ }
140
+ /**
141
+ * Turn a route's advertised levels into picker rows.
142
+ *
143
+ * The provider default always leads, because clearing an explicit effort is a
144
+ * choice in its own right: the reader who raised it must be able to put it back
145
+ * without knowing what the adapter would otherwise send.
146
+ */
147
+ export declare function effortChoices(efforts: readonly {
148
+ readonly id: string;
149
+ readonly name: string;
150
+ readonly description?: string;
151
+ }[], effective: string | undefined): readonly EffortChoice[];
152
+ /**
153
+ * One reasoning effort chosen by key press.
154
+ *
155
+ * The levels are fixed once the reader asks for the list, because they come
156
+ * from the route that was in force when the picker opened; the route itself
157
+ * cannot change while the list owns the keyboard.
158
+ */
159
+ export declare class EffortPicker extends ListPicker<EffortChoice> {
160
+ constructor(choices: () => readonly EffortChoice[], heading: string, keys: () => Keymap);
102
161
  }
103
162
  //# sourceMappingURL=picker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"picker.d.ts","sourceRoot":"","sources":["../../src/ui/picker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"picker.d.ts","sourceRoot":"","sources":["../../src/ui/picker.ts"],"names":[],"mappings":"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"}
package/lib/ui/picker.js CHANGED
@@ -1,4 +1,8 @@
1
1
  import { matchesKey } from '@earendil-works/pi-tui';
2
+ import { hintKeys, matchesAction, moveHint } from "../input/actions.js";
3
+ import { pastedText } from "../input.js";
4
+ import { matchScore } from "../input/match.js";
5
+ import { describeModelRoute, modelRouteKey } from "../agent/model.js";
2
6
  import { describePreset } from "../agent/presets.js";
3
7
  /**
4
8
  * Rows the picker shows at once.
@@ -38,6 +42,7 @@ export class ListPicker {
38
42
  describe;
39
43
  haystackOf;
40
44
  hints;
45
+ keys;
41
46
  cursor = 0;
42
47
  filter = '';
43
48
  note;
@@ -45,20 +50,29 @@ export class ListPicker {
45
50
  /** The value a pick settles on. */
46
51
  idOf, describe,
47
52
  /** Extra text the filter matches besides the row's own label. */
48
- haystackOf, hints) {
53
+ haystackOf, hints,
54
+ /** The keys in force, read per press so a settings edit lands on the next key. */
55
+ keys) {
49
56
  this.source = source;
50
57
  this.heading = heading;
51
58
  this.idOf = idOf;
52
59
  this.describe = describe;
53
60
  this.haystackOf = haystackOf;
54
61
  this.hints = hints;
62
+ this.keys = keys;
55
63
  }
56
- /** Rows matching the typed filter, in the order they were listed. */
64
+ /** Rows matching the typed filter, best match first. */
57
65
  visible() {
58
- const needle = this.filter.trim().toLowerCase();
66
+ const needle = this.filter.trim();
59
67
  if (needle === '')
60
68
  return this.source();
61
- return this.source().filter(row => this.haystackOf(row).toLowerCase().includes(needle));
69
+ // Ties keep the order the caller listed them in, so rows do not shuffle
70
+ // under the cursor while the reader is still typing.
71
+ return this.source()
72
+ .map(row => ({ row, score: matchScore(needle, this.haystackOf(row)) }))
73
+ .filter((entry) => entry.score !== undefined)
74
+ .sort((left, right) => right.score - left.score)
75
+ .map(entry => entry.row);
62
76
  }
63
77
  /**
64
78
  * Say why the row under the cursor cannot be taken.
@@ -74,17 +88,20 @@ export class ListPicker {
74
88
  handleKey(data) {
75
89
  this.note = undefined;
76
90
  const rows = this.visible();
77
- if (matchesKey(data, 'escape'))
91
+ // A picker owns the keyboard while it is open, so the interrupt key has to
92
+ // mean "leave this list" here: swallowing it would strand the reader.
93
+ const keys = this.keys();
94
+ if (matchesAction(keys, 'picker.cancel', data))
78
95
  return { kind: 'cancel' };
79
- if (matchesKey(data, 'enter')) {
96
+ if (matchesAction(keys, 'picker.confirm', data)) {
80
97
  const chosen = rows[Math.min(this.cursor, Math.max(0, rows.length - 1))];
81
98
  return chosen === undefined ? undefined : { kind: 'pick', id: this.idOf(chosen) };
82
99
  }
83
- if (matchesKey(data, 'up')) {
100
+ if (matchesAction(keys, 'picker.up', data)) {
84
101
  this.cursor = Math.max(0, this.cursor - 1);
85
102
  return undefined;
86
103
  }
87
- if (matchesKey(data, 'down')) {
104
+ if (matchesAction(keys, 'picker.down', data)) {
88
105
  this.cursor = Math.min(Math.max(0, rows.length - 1), this.cursor + 1);
89
106
  return undefined;
90
107
  }
@@ -98,8 +115,9 @@ export class ListPicker {
98
115
  this.cursor = 0;
99
116
  return undefined;
100
117
  }
101
- if (data.length === 1 && data >= ' ') {
102
- this.filter += data;
118
+ const text = pastedText(data) ?? (data.length === 1 && data >= ' ' ? data : undefined);
119
+ if (text !== undefined) {
120
+ this.filter += text;
103
121
  this.cursor = 0;
104
122
  }
105
123
  return undefined;
@@ -119,7 +137,7 @@ export class ListPicker {
119
137
  above: start,
120
138
  below: Math.max(0, rows.length - start - window.length),
121
139
  filter: this.filter,
122
- hint: rows.length === 0 ? this.hints.empty : this.hints.listed,
140
+ hint: rows.length === 0 ? this.hints.empty() : this.hints.listed(),
123
141
  };
124
142
  }
125
143
  }
@@ -131,7 +149,7 @@ export class ListPicker {
131
149
  * first paint would make opening the picker as slow as the slowest session.
132
150
  */
133
151
  export class SessionPicker extends ListPicker {
134
- constructor(sessions, titles, now = () => Date.now()) {
152
+ constructor(sessions, titles, now = () => Date.now(), keys) {
135
153
  const labelOf = (session) => titles().get(session.id) ?? session.id;
136
154
  super(() => sessions, () => `resume a session · ${sessions.length} stored`, session => session.id, session => ({
137
155
  label: labelOf(session),
@@ -143,9 +161,9 @@ export class SessionPicker extends ListPicker {
143
161
  // The card marks the row under the cursor, which the list decides.
144
162
  current: false,
145
163
  }), session => [labelOf(session), session.id, session.cwd ?? ''].join(' '), {
146
- empty: 'nothing matches · backspace to widen · esc cancel',
147
- listed: '↑↓ move · enter open · esc cancel · type to filter',
148
- });
164
+ empty: () => `nothing matches · backspace to widen · ${hintKeys(keys(), 'picker.cancel')} cancel`,
165
+ listed: () => `${moveHint(keys(), 'picker.up', 'picker.down')} move · ${hintKeys(keys(), 'picker.confirm')} open · ${hintKeys(keys(), 'picker.cancel')} cancel · type to filter`,
166
+ }, keys);
149
167
  }
150
168
  }
151
169
  /**
@@ -155,11 +173,86 @@ export class SessionPicker extends ListPicker {
155
173
  * the picker is open is present or gone without reopening it.
156
174
  */
157
175
  export class PresetPicker extends ListPicker {
158
- constructor(presets, currentId) {
176
+ constructor(presets, currentId, keys) {
159
177
  super(presets, () => `agent preset · ${presets().length} available`, preset => preset.id, preset => describePreset(preset, currentId()), preset => [preset.id, preset.name ?? '', preset.description ?? ''].join(' '), {
160
- empty: 'nothing matches · backspace to widen · esc cancel',
161
- listed: '↑↓ move · enter switch · esc cancel · type to filter',
162
- });
178
+ empty: () => `nothing matches · backspace to widen · ${hintKeys(keys(), 'picker.cancel')} cancel`,
179
+ listed: () => `${moveHint(keys(), 'picker.up', 'picker.down')} move · ${hintKeys(keys(), 'picker.confirm')} switch · ${hintKeys(keys(), 'picker.cancel')} cancel · type to filter`,
180
+ }, keys);
181
+ }
182
+ }
183
+ /**
184
+ * One configured model route chosen by key press.
185
+ *
186
+ * Rows are the caller's and are re-read on every key and paint, so a provider
187
+ * whose model list arrives after the picker opened appears in it without
188
+ * reopening, and the filter the reader already typed applies to those late
189
+ * rows too.
190
+ */
191
+ export class ModelPicker extends ListPicker {
192
+ constructor(routes, current, keys) {
193
+ super(routes, () => {
194
+ const chosen = current();
195
+ if (chosen === undefined)
196
+ return 'model · no route in use';
197
+ const effort = chosen.reasoningEffort === undefined ? '' : ` (${chosen.reasoningEffort})`;
198
+ return `model · current ${chosen.provider}/${chosen.model}${effort}`;
199
+ }, route => modelRouteKey(route), route => describeModelRoute(route, current()), route => [route.provider, route.model, route.name].join(' '), {
200
+ empty: () => `nothing matched · /model <provider>/<model> takes any id · backspace to widen · ${hintKeys(keys(), 'picker.cancel')} cancel`,
201
+ listed: () => `${moveHint(keys(), 'picker.up', 'picker.down')} move · ${hintKeys(keys(), 'picker.confirm')} switch · ${hintKeys(keys(), 'picker.cancel')} cancel · type to filter`,
202
+ }, keys);
203
+ }
204
+ }
205
+ /**
206
+ * The pick id that clears an explicit effort.
207
+ *
208
+ * An absent effort is a real choice — it restores the model's own default — so
209
+ * it needs an id, and no adapter-owned effort may be empty.
210
+ */
211
+ export const PROVIDER_DEFAULT_EFFORT_ID = '';
212
+ /**
213
+ * Turn a route's advertised levels into picker rows.
214
+ *
215
+ * The provider default always leads, because clearing an explicit effort is a
216
+ * choice in its own right: the reader who raised it must be able to put it back
217
+ * without knowing what the adapter would otherwise send.
218
+ */
219
+ export function effortChoices(efforts, effective) {
220
+ return [
221
+ {
222
+ id: PROVIDER_DEFAULT_EFFORT_ID,
223
+ name: 'provider default',
224
+ description: 'clear the explicit effort',
225
+ current: effective === undefined,
226
+ },
227
+ ...efforts.map(effort => ({
228
+ id: effort.id,
229
+ name: effort.name,
230
+ ...(effort.description === undefined ? {} : { description: effort.description }),
231
+ current: effort.id === effective,
232
+ })),
233
+ ];
234
+ }
235
+ /**
236
+ * One reasoning effort chosen by key press.
237
+ *
238
+ * The levels are fixed once the reader asks for the list, because they come
239
+ * from the route that was in force when the picker opened; the route itself
240
+ * cannot change while the list owns the keyboard.
241
+ */
242
+ export class EffortPicker extends ListPicker {
243
+ constructor(choices, heading, keys) {
244
+ super(choices, () => heading, choice => choice.id, choice => ({
245
+ label: choice.name,
246
+ description: [
247
+ choice.description,
248
+ choice.id !== choice.name ? choice.id : undefined,
249
+ choice.current ? 'current' : undefined,
250
+ ].filter(part => part !== undefined && part !== '').join(' · ') || undefined,
251
+ current: choice.current,
252
+ }), choice => [choice.name, choice.id, choice.description ?? ''].join(' '), {
253
+ empty: () => `nothing matches · backspace to widen · ${hintKeys(keys(), 'picker.cancel')} cancel`,
254
+ listed: () => `${moveHint(keys(), 'picker.up', 'picker.down')} move · ${hintKeys(keys(), 'picker.confirm')} apply · ${hintKeys(keys(), 'picker.cancel')} cancel · type to filter`,
255
+ }, keys);
163
256
  }
164
257
  }
165
258
  //# sourceMappingURL=picker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"picker.js","sourceRoot":"","sources":["../../src/ui/picker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"picker.js","sourceRoot":"","sources":["../../src/ui/picker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { Component } from '@earendil-works/pi-tui';
2
+ import type { BoxedEditor } from './editor.ts';
3
+ /**
4
+ * The prompt bar, and the question that borrows it.
5
+ *
6
+ * A question is answered in the reader's own editor, because that is the one
7
+ * with everything they expect of it — completion, history, undo, and the keys
8
+ * their terminal sends — so the question takes the bar rather than a copy of it.
9
+ * The bar hides while the question is open, and the prompt nobody has sent yet
10
+ * is held aside and put back afterwards.
11
+ */
12
+ export declare class PromptBar implements Component {
13
+ private readonly editor;
14
+ private borrowed;
15
+ private held;
16
+ constructor(editor: BoxedEditor);
17
+ /**
18
+ * Borrow the editor for a gate that collects answers in it.
19
+ *
20
+ * The builder runs after the prompt is held aside, because a gate empties the
21
+ * editor for its first answer as it is built, and a prompt is not an answer.
22
+ */
23
+ borrow<T>(build: () => T): T;
24
+ /** Give the editor back, with the prompt that was in it. */
25
+ giveBack(): void;
26
+ /** The rows the bar occupies, which a borrowing question leaves empty. */
27
+ render(width: number): string[];
28
+ invalidate(): void;
29
+ }
30
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/ui/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C;;;;;;;;GAQG;AACH,qBAAa,SAAU,YAAW,SAAS;IAI7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,IAAI,CAAK;gBAEY,MAAM,EAAE,WAAW;IAEhD;;;;;OAKG;IACH,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;IAO5B,4DAA4D;IAC5D,QAAQ,IAAI,IAAI;IAOhB,0EAA0E;IAC1E,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAI/B,UAAU,IAAI,IAAI;CAGnB"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The prompt bar, and the question that borrows it.
3
+ *
4
+ * A question is answered in the reader's own editor, because that is the one
5
+ * with everything they expect of it — completion, history, undo, and the keys
6
+ * their terminal sends — so the question takes the bar rather than a copy of it.
7
+ * The bar hides while the question is open, and the prompt nobody has sent yet
8
+ * is held aside and put back afterwards.
9
+ */
10
+ export class PromptBar {
11
+ editor;
12
+ borrowed = false;
13
+ held = '';
14
+ constructor(editor) {
15
+ this.editor = editor;
16
+ }
17
+ /**
18
+ * Borrow the editor for a gate that collects answers in it.
19
+ *
20
+ * The builder runs after the prompt is held aside, because a gate empties the
21
+ * editor for its first answer as it is built, and a prompt is not an answer.
22
+ */
23
+ borrow(build) {
24
+ this.held = this.editor.getExpandedText();
25
+ this.editor.setText('');
26
+ this.borrowed = true;
27
+ return build();
28
+ }
29
+ /** Give the editor back, with the prompt that was in it. */
30
+ giveBack() {
31
+ if (!this.borrowed)
32
+ return;
33
+ this.borrowed = false;
34
+ this.editor.setText(this.held);
35
+ this.held = '';
36
+ }
37
+ /** The rows the bar occupies, which a borrowing question leaves empty. */
38
+ render(width) {
39
+ return this.borrowed ? [] : this.editor.render(width);
40
+ }
41
+ invalidate() {
42
+ this.editor.invalidate();
43
+ }
44
+ }
45
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/ui/prompt.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,OAAO,SAAS;IAIS;IAHrB,QAAQ,GAAG,KAAK,CAAA;IAChB,IAAI,GAAG,EAAE,CAAA;IAEjB,YAA6B,MAAmB;QAAnB,WAAM,GAAN,MAAM,CAAa;IAAG,CAAC;IAEpD;;;;;OAKG;IACH,MAAM,CAAI,KAAc;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAA;QACzC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACvB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACpB,OAAO,KAAK,EAAE,CAAA;IAChB,CAAC;IAED,4DAA4D;IAC5D,QAAQ;QACN,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAM;QAC1B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;QACrB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9B,IAAI,CAAC,IAAI,GAAG,EAAE,CAAA;IAChB,CAAC;IAED,0EAA0E;IAC1E,MAAM,CAAC,KAAa;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACvD,CAAC;IAED,UAAU;QACR,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAA;IAC1B,CAAC;CACF"}