@zergai/ztc 0.2.6-dev.36101352252 → 0.2.7-dev.36236183737
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -17
- package/bin/zmux-darwin-arm64 +0 -0
- package/bin/ztc-tui-darwin-arm64 +0 -0
- package/bin/zterm-darwin-arm64 +0 -0
- package/dist/App.js +19 -5
- package/dist/agent/agent.d.ts +5 -1
- package/dist/agent/agent.js +51 -8
- package/dist/agent/backends/account_pool.d.ts +5 -6
- package/dist/agent/backends/account_pool.js +39 -14
- package/dist/agent/backends/account_rotation.d.ts +3 -0
- package/dist/agent/backends/account_rotation.js +14 -3
- package/dist/agent/backends/codex_account_status.d.ts +42 -0
- package/dist/agent/backends/codex_account_status.js +196 -0
- package/dist/agent/backends/codex_app_server.d.ts +12 -2
- package/dist/agent/backends/codex_app_server.js +66 -6
- package/dist/agent/backends/index.d.ts +2 -0
- package/dist/agent/backends/index.js +13 -5
- package/dist/agent/backends/openai.d.ts +2 -2
- package/dist/agent/backends/openai.js +4 -3
- package/dist/agent/backends/openai_compatible.js +10 -10
- package/dist/agent/backends/openai_responses.d.ts +17 -5
- package/dist/agent/backends/openai_responses.js +2 -4
- package/dist/agent/backends/token_usage.js +1 -1
- package/dist/agent/backends/types.d.ts +3 -0
- package/dist/agent/commands/accounts.d.ts +7 -1
- package/dist/agent/commands/accounts.js +299 -101
- package/dist/agent/commands/config.js +11 -3
- package/dist/agent/commands/config_profile_switch.d.ts +2 -0
- package/dist/agent/commands/config_profile_switch.js +22 -0
- package/dist/agent/commands/context.js +4 -3
- package/dist/agent/commands/index.js +1 -2
- package/dist/agent/commands/input_mode.js +1 -1
- package/dist/agent/commands/model.js +7 -2
- package/dist/agent/commands/plan.d.ts +12 -0
- package/dist/agent/commands/plan.js +39 -28
- package/dist/agent/commands/profile.d.ts +1 -1
- package/dist/agent/commands/profile.js +34 -257
- package/dist/agent/commands/provider_choices.d.ts +12 -1
- package/dist/agent/commands/provider_choices.js +29 -2
- package/dist/agent/commands/provider_selection.d.ts +3 -0
- package/dist/agent/commands/provider_selection.js +63 -0
- package/dist/agent/commands/settings.d.ts +2 -0
- package/dist/agent/commands/settings.js +655 -50
- package/dist/agent/commands/types.d.ts +19 -2
- package/dist/agent/tools/ask_user.js +2 -2
- package/dist/app/agent_runner.d.ts +1 -1
- package/dist/app/agent_runner.js +2 -2
- package/dist/app/ask_user_response.d.ts +3 -0
- package/dist/app/ask_user_response.js +16 -0
- package/dist/app/command_context.js +29 -13
- package/dist/app/controller.d.ts +17 -2
- package/dist/app/controller.js +24 -1
- package/dist/app/selection_completion.d.ts +9 -3
- package/dist/app/selection_completion.js +54 -22
- package/dist/cli_args.js +10 -1
- package/dist/cli_main.js +85 -2
- package/dist/cli_ratatui.d.ts +22 -4
- package/dist/cli_ratatui.js +421 -146
- package/dist/config/defaults.d.ts +6 -0
- package/dist/config/defaults.js +20 -0
- package/dist/config/profiles.d.ts +9 -0
- package/dist/config/profiles.js +87 -0
- package/dist/config/types.d.ts +2 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.js +283 -40
- package/dist/headless.js +14 -0
- package/dist/panes/model_catalog.d.ts +1 -1
- package/dist/panes/model_catalog.js +24 -2
- package/dist/panes/ztc_launch.js +6 -0
- package/dist/router_auth.js +3 -2
- package/dist/session.d.ts +2 -0
- package/dist/session.js +3 -0
- package/dist/types.d.ts +23 -2
- package/dist/ui/views/app.d.ts +3 -1
- package/dist/ui/views/app.js +3 -2
- package/dist/ui/views/completion_menu.js +6 -6
- package/dist/ui/views/input_area.d.ts +2 -1
- package/dist/ui/views/input_area.js +9 -8
- package/dist/ui/views/status_bar.d.ts +2 -0
- package/dist/ui/views/status_bar.js +15 -4
- package/dist/ui/widgets/color_panel.d.ts +9 -0
- package/dist/ui/widgets/color_panel.js +41 -26
- package/dist/ui/widgets/navigator_panel.d.ts +9 -0
- package/dist/ui/widgets/navigator_panel.js +17 -16
- package/dist/ui/widgets/panel_frame.d.ts +83 -3
- package/dist/ui/widgets/panel_frame.js +107 -9
- package/dist/ui/widgets/questionnaire.d.ts +9 -0
- package/dist/ui/widgets/questionnaire.js +214 -16
- package/dist/ui/widgets/resume_panel.d.ts +9 -0
- package/dist/ui/widgets/resume_panel.js +18 -17
- package/dist/ui/widgets/rewind_panel.d.ts +9 -0
- package/dist/ui/widgets/rewind_panel.js +15 -16
- package/dist/ui/widgets/select.d.ts +6 -0
- package/dist/ui/widgets/select.js +47 -12
- package/dist/ui/widgets/settings_panel.d.ts +75 -0
- package/dist/ui/widgets/settings_panel.js +197 -39
- package/dist/ui/widgets/status_line_panel.d.ts +9 -0
- package/dist/ui/widgets/status_line_panel.js +18 -19
- package/dist/ui/widgets/transcript_preview.d.ts +8 -0
- package/dist/ui/widgets/transcript_preview.js +10 -0
- package/dist/utils/context.js +2 -0
- package/dist/utils/fireworks.d.ts +20 -0
- package/dist/utils/fireworks.js +23 -0
- package/dist/utils/models.d.ts +2 -1
- package/dist/utils/models.js +19 -0
- package/dist/web/accounts_mirror.d.ts +7 -0
- package/dist/web/accounts_mirror.js +59 -7
- package/dist/web/mirror_stream.js +19 -5
- package/dist/zlm-embed.mjs +5734 -5362
- package/package.json +2 -2
- package/dist/agent/commands/provider.d.ts +0 -2
- package/dist/agent/commands/provider.js +0 -75
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* relative-time helpers live here so every picker draws the same chrome at the
|
|
6
6
|
* same widths.
|
|
7
7
|
*/
|
|
8
|
+
import { type LayoutNode } from '../core/index.js';
|
|
8
9
|
import type { TextStyle } from '../core/types.js';
|
|
9
10
|
export interface StyledSegment {
|
|
10
11
|
text: string;
|
|
@@ -77,6 +78,38 @@ export declare function framedLine(segments: StyledSegment[], width: number, bac
|
|
|
77
78
|
export declare function bottomBorder(width: number): StyledLine;
|
|
78
79
|
/** `just now`, `12m ago`, `3h ago`, `2d ago` — coarse on purpose. */
|
|
79
80
|
export declare function formatRelativeTime(isoTimestamp: string, nowMs: number): string;
|
|
81
|
+
/**
|
|
82
|
+
* Build a full-page panel's styled view from its finished lines.
|
|
83
|
+
*
|
|
84
|
+
* Every full-page panel draws a framed surface and hands it to the host the
|
|
85
|
+
* same way, so the shape lives here rather than once per panel: a column of
|
|
86
|
+
* one-row boxes, offset by the surface's centring margin. Without the shared
|
|
87
|
+
* margin each panel would have to remember to re-emit it, and the one that
|
|
88
|
+
* forgot would paint at a different column from the page beside it.
|
|
89
|
+
*
|
|
90
|
+
* The margin is `marginLeft` on the frame rather than leading spaces in the
|
|
91
|
+
* text. The renderer then places the frame, and the panel's hit-test bands —
|
|
92
|
+
* which carry the same margin — describe the columns it landed on. Carrying it
|
|
93
|
+
* in both would double it.
|
|
94
|
+
*/
|
|
95
|
+
export declare function buildWidgetFrameView(lines: StyledLine[], inset: number): LayoutNode;
|
|
96
|
+
/**
|
|
97
|
+
* The frame for a full-page panel, plus the margin it was placed at.
|
|
98
|
+
*
|
|
99
|
+
* A panel asks for the whole usable width and gets the shared cap on top, so
|
|
100
|
+
* every page draws at the same column on the same terminal; below the cap the
|
|
101
|
+
* frame keeps the full width it asked for.
|
|
102
|
+
*
|
|
103
|
+
* The frame is flush left, so the margin is zero and the spare columns sit to
|
|
104
|
+
* its right. It stays in the signature because the hit-test bands consume it.
|
|
105
|
+
*
|
|
106
|
+
* `termCols` is the terminal, not this surface: the host wraps every work
|
|
107
|
+
* surface in a `paddingX: 1` column, so `termCols - 2` is the usable width.
|
|
108
|
+
*/
|
|
109
|
+
export declare function widgetFrameGeometry(termCols: number): {
|
|
110
|
+
width: number;
|
|
111
|
+
inset: number;
|
|
112
|
+
};
|
|
80
113
|
/** Lines one wheel notch scrolls a picker pane, matching zmux's own step. */
|
|
81
114
|
export declare const WHEEL_LINES = 3;
|
|
82
115
|
/** Left frame cell plus its space, before the first content column. */
|
|
@@ -86,6 +119,10 @@ export declare const PANE_DIVIDER_WIDTH = 3;
|
|
|
86
119
|
/**
|
|
87
120
|
* A pane's scrollable rectangle in surface coordinates.
|
|
88
121
|
*
|
|
122
|
+
* `inset` is the surface's centring margin: every band helper takes it so the
|
|
123
|
+
* hit-test columns follow the frame when a wide terminal caps it. A band left
|
|
124
|
+
* at the terminal origin would scroll a pane the pointer is not over.
|
|
125
|
+
*
|
|
89
126
|
* Rows and columns count from the surface's own top-left corner, not the
|
|
90
127
|
* terminal's: the host translates terminal cells into the widget's frame before
|
|
91
128
|
* calling `handleMouse`, so a band recorded at paint time is directly
|
|
@@ -111,6 +148,49 @@ export interface PaneBands {
|
|
|
111
148
|
list: PaneBand;
|
|
112
149
|
preview: PaneBand;
|
|
113
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Widest frame a full-page surface draws.
|
|
153
|
+
*
|
|
154
|
+
* Past roughly this many columns a two-column table stops reading as a table:
|
|
155
|
+
* the label and its value drift to opposite edges and the eye has to sweep the
|
|
156
|
+
* whole pane to pair them. 100 columns keeps a category rail, a label column,
|
|
157
|
+
* and a value column inside one glance on a normal font, and holds a preview
|
|
158
|
+
* pane beside its list without stranding either. Every full-page panel draws
|
|
159
|
+
* its frame at this width on a wider terminal.
|
|
160
|
+
*/
|
|
161
|
+
export declare const DEFAULT_MAX_SURFACE_WIDTH = 100;
|
|
162
|
+
/**
|
|
163
|
+
* Narrowest frame a capped surface keeps.
|
|
164
|
+
*
|
|
165
|
+
* A clamp is not a floor: a terminal narrower than this still gets every column
|
|
166
|
+
* it has. The value exists so the cap and the floor are both spelled out, and so
|
|
167
|
+
* a caller can ask what the surface would have drawn at.
|
|
168
|
+
*/
|
|
169
|
+
export declare const MIN_CAPPED_SURFACE_WIDTH = 24;
|
|
170
|
+
/**
|
|
171
|
+
* The frame width a surface should draw at, and the column it starts on.
|
|
172
|
+
*
|
|
173
|
+
* A surface may declare a cap, the widest frame its content still reads well
|
|
174
|
+
* at. Every full-page panel shares the one cap so the pickers line up: they are
|
|
175
|
+
* opened and dismissed constantly and the user is looking at one at a time, so
|
|
176
|
+
* a page drawn at a different width from its neighbour would make the frame
|
|
177
|
+
* jump sideways on every switch. The cap also keeps a two-column table
|
|
178
|
+
* readable — past it a label and its value drift to opposite edges and the eye
|
|
179
|
+
* has to sweep the whole pane to pair them.
|
|
180
|
+
*
|
|
181
|
+
* The frame is left-aligned, not centred. A centred frame on a wide terminal
|
|
182
|
+
* leaves a black band down the left of the pane, which reads as the card having
|
|
183
|
+
* been pushed off-centre; the spare columns are all spent on the right instead.
|
|
184
|
+
* `inset` stays in the return type because the hit-test bands take it — it is
|
|
185
|
+
* zero while the frame is flush left, and the bands follow the frame.
|
|
186
|
+
*
|
|
187
|
+
* Below the cap nothing is reserved: a terminal that cannot afford the margin
|
|
188
|
+
* gets every column it asked for.
|
|
189
|
+
*/
|
|
190
|
+
export declare function centeredSurface(availableWidth: number, maxWidth?: number): {
|
|
191
|
+
width: number;
|
|
192
|
+
inset: number;
|
|
193
|
+
};
|
|
114
194
|
/**
|
|
115
195
|
* One band covering a panel's whole body.
|
|
116
196
|
*
|
|
@@ -121,12 +201,12 @@ export interface PaneBands {
|
|
|
121
201
|
* panel, which is the behaviour a user expects from a surface they are
|
|
122
202
|
* pointing at.
|
|
123
203
|
*/
|
|
124
|
-
export declare function bodyBand(top: number, bottom: number, innerWidth: number): PaneBand;
|
|
204
|
+
export declare function bodyBand(top: number, bottom: number, innerWidth: number, inset?: number): PaneBand;
|
|
125
205
|
/**
|
|
126
206
|
* Both panes' bands for a side-by-side layout, where the panes share one
|
|
127
207
|
* heading row and differ only in columns.
|
|
128
208
|
*/
|
|
129
|
-
export declare function sideBySideBands(headerRow: number, lastRow: number, listWidth: number, previewWidth: number): PaneBands;
|
|
209
|
+
export declare function sideBySideBands(headerRow: number, lastRow: number, listWidth: number, previewWidth: number, inset?: number): PaneBands;
|
|
130
210
|
/**
|
|
131
211
|
* Both panes' bands for a stacked layout.
|
|
132
212
|
*
|
|
@@ -139,4 +219,4 @@ export declare function stackedBands(listRows: {
|
|
|
139
219
|
}, previewRows: {
|
|
140
220
|
top: number;
|
|
141
221
|
bottom: number;
|
|
142
|
-
}, innerWidth: number): PaneBands;
|
|
222
|
+
}, innerWidth: number, inset?: number): PaneBands;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* relative-time helpers live here so every picker draws the same chrome at the
|
|
6
6
|
* same widths.
|
|
7
7
|
*/
|
|
8
|
+
import { box, text } from '../core/index.js';
|
|
8
9
|
import { displayWidth, sanitizeTerminalText } from '../core/text_width.js';
|
|
9
10
|
import { TERMINAL_THEME } from '../views/theme.js';
|
|
10
11
|
const graphemes = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
@@ -184,6 +185,52 @@ export function formatRelativeTime(isoTimestamp, nowMs) {
|
|
|
184
185
|
return `${months}mo ago`;
|
|
185
186
|
return `${Math.floor(months / 12)}y ago`;
|
|
186
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Build a full-page panel's styled view from its finished lines.
|
|
190
|
+
*
|
|
191
|
+
* Every full-page panel draws a framed surface and hands it to the host the
|
|
192
|
+
* same way, so the shape lives here rather than once per panel: a column of
|
|
193
|
+
* one-row boxes, offset by the surface's centring margin. Without the shared
|
|
194
|
+
* margin each panel would have to remember to re-emit it, and the one that
|
|
195
|
+
* forgot would paint at a different column from the page beside it.
|
|
196
|
+
*
|
|
197
|
+
* The margin is `marginLeft` on the frame rather than leading spaces in the
|
|
198
|
+
* text. The renderer then places the frame, and the panel's hit-test bands —
|
|
199
|
+
* which carry the same margin — describe the columns it landed on. Carrying it
|
|
200
|
+
* in both would double it.
|
|
201
|
+
*/
|
|
202
|
+
export function buildWidgetFrameView(lines, inset) {
|
|
203
|
+
const frame = box(lines.map(line => box(line.segments.map(segment => text(segment.text, segment.style)), {
|
|
204
|
+
flexDirection: 'row',
|
|
205
|
+
height: 1,
|
|
206
|
+
flexShrink: 0,
|
|
207
|
+
backgroundColor: line.backgroundColor,
|
|
208
|
+
})), {
|
|
209
|
+
flexDirection: 'column',
|
|
210
|
+
height: lines.length,
|
|
211
|
+
flexShrink: 0,
|
|
212
|
+
backgroundColor: TERMINAL_THEME.bg,
|
|
213
|
+
});
|
|
214
|
+
return inset > 0
|
|
215
|
+
? box([frame], { flexDirection: 'column', marginLeft: inset, flexShrink: 0 })
|
|
216
|
+
: frame;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The frame for a full-page panel, plus the margin it was placed at.
|
|
220
|
+
*
|
|
221
|
+
* A panel asks for the whole usable width and gets the shared cap on top, so
|
|
222
|
+
* every page draws at the same column on the same terminal; below the cap the
|
|
223
|
+
* frame keeps the full width it asked for.
|
|
224
|
+
*
|
|
225
|
+
* The frame is flush left, so the margin is zero and the spare columns sit to
|
|
226
|
+
* its right. It stays in the signature because the hit-test bands consume it.
|
|
227
|
+
*
|
|
228
|
+
* `termCols` is the terminal, not this surface: the host wraps every work
|
|
229
|
+
* surface in a `paddingX: 1` column, so `termCols - 2` is the usable width.
|
|
230
|
+
*/
|
|
231
|
+
export function widgetFrameGeometry(termCols) {
|
|
232
|
+
return centeredSurface(termCols - 2);
|
|
233
|
+
}
|
|
187
234
|
// ── Mouse hit-testing ────────────────────────────────────────────────────────
|
|
188
235
|
/** Lines one wheel notch scrolls a picker pane, matching zmux's own step. */
|
|
189
236
|
export const WHEEL_LINES = 3;
|
|
@@ -203,6 +250,56 @@ export function isInsideBand(band, x, y) {
|
|
|
203
250
|
return false;
|
|
204
251
|
return y >= band.y0 && y <= band.y1 && x >= band.x0 && x <= band.x1;
|
|
205
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Widest frame a full-page surface draws.
|
|
255
|
+
*
|
|
256
|
+
* Past roughly this many columns a two-column table stops reading as a table:
|
|
257
|
+
* the label and its value drift to opposite edges and the eye has to sweep the
|
|
258
|
+
* whole pane to pair them. 100 columns keeps a category rail, a label column,
|
|
259
|
+
* and a value column inside one glance on a normal font, and holds a preview
|
|
260
|
+
* pane beside its list without stranding either. Every full-page panel draws
|
|
261
|
+
* its frame at this width on a wider terminal.
|
|
262
|
+
*/
|
|
263
|
+
export const DEFAULT_MAX_SURFACE_WIDTH = 100;
|
|
264
|
+
/**
|
|
265
|
+
* Narrowest frame a capped surface keeps.
|
|
266
|
+
*
|
|
267
|
+
* A clamp is not a floor: a terminal narrower than this still gets every column
|
|
268
|
+
* it has. The value exists so the cap and the floor are both spelled out, and so
|
|
269
|
+
* a caller can ask what the surface would have drawn at.
|
|
270
|
+
*/
|
|
271
|
+
export const MIN_CAPPED_SURFACE_WIDTH = 24;
|
|
272
|
+
/**
|
|
273
|
+
* The frame width a surface should draw at, and the column it starts on.
|
|
274
|
+
*
|
|
275
|
+
* A surface may declare a cap, the widest frame its content still reads well
|
|
276
|
+
* at. Every full-page panel shares the one cap so the pickers line up: they are
|
|
277
|
+
* opened and dismissed constantly and the user is looking at one at a time, so
|
|
278
|
+
* a page drawn at a different width from its neighbour would make the frame
|
|
279
|
+
* jump sideways on every switch. The cap also keeps a two-column table
|
|
280
|
+
* readable — past it a label and its value drift to opposite edges and the eye
|
|
281
|
+
* has to sweep the whole pane to pair them.
|
|
282
|
+
*
|
|
283
|
+
* The frame is left-aligned, not centred. A centred frame on a wide terminal
|
|
284
|
+
* leaves a black band down the left of the pane, which reads as the card having
|
|
285
|
+
* been pushed off-centre; the spare columns are all spent on the right instead.
|
|
286
|
+
* `inset` stays in the return type because the hit-test bands take it — it is
|
|
287
|
+
* zero while the frame is flush left, and the bands follow the frame.
|
|
288
|
+
*
|
|
289
|
+
* Below the cap nothing is reserved: a terminal that cannot afford the margin
|
|
290
|
+
* gets every column it asked for.
|
|
291
|
+
*/
|
|
292
|
+
export function centeredSurface(availableWidth, maxWidth = DEFAULT_MAX_SURFACE_WIDTH) {
|
|
293
|
+
const available = Math.max(1, Math.floor(availableWidth));
|
|
294
|
+
// Never wider than the room, never narrower than the floor, so a terminal
|
|
295
|
+
// that is already tighter than the floor keeps its own columns.
|
|
296
|
+
const capped = Math.min(available, Math.max(MIN_CAPPED_SURFACE_WIDTH, Math.floor(maxWidth)));
|
|
297
|
+
// Left-aligned: the frame starts at the pane's first column and the spare
|
|
298
|
+
// width sits to its right. Centring it left a black band on the left of a
|
|
299
|
+
// wide pane (and, with the host's `paddingX: 1`, one column more of it than
|
|
300
|
+
// on the right), which read as the card having been pushed off-centre.
|
|
301
|
+
return { width: capped, inset: 0 };
|
|
302
|
+
}
|
|
206
303
|
/**
|
|
207
304
|
* One band covering a panel's whole body.
|
|
208
305
|
*
|
|
@@ -213,21 +310,22 @@ export function isInsideBand(band, x, y) {
|
|
|
213
310
|
* panel, which is the behaviour a user expects from a surface they are
|
|
214
311
|
* pointing at.
|
|
215
312
|
*/
|
|
216
|
-
export function bodyBand(top, bottom, innerWidth) {
|
|
313
|
+
export function bodyBand(top, bottom, innerWidth, inset = 0) {
|
|
314
|
+
const x0 = CONTENT_INSET_X + inset;
|
|
217
315
|
return {
|
|
218
316
|
y0: top,
|
|
219
317
|
y1: bottom,
|
|
220
|
-
x0
|
|
221
|
-
x1:
|
|
318
|
+
x0,
|
|
319
|
+
x1: x0 + innerWidth - 1,
|
|
222
320
|
};
|
|
223
321
|
}
|
|
224
322
|
/**
|
|
225
323
|
* Both panes' bands for a side-by-side layout, where the panes share one
|
|
226
324
|
* heading row and differ only in columns.
|
|
227
325
|
*/
|
|
228
|
-
export function sideBySideBands(headerRow, lastRow, listWidth, previewWidth) {
|
|
229
|
-
const listX0 = CONTENT_INSET_X;
|
|
230
|
-
const previewX0 = CONTENT_INSET_X + listWidth + PANE_DIVIDER_WIDTH;
|
|
326
|
+
export function sideBySideBands(headerRow, lastRow, listWidth, previewWidth, inset = 0) {
|
|
327
|
+
const listX0 = CONTENT_INSET_X + inset;
|
|
328
|
+
const previewX0 = CONTENT_INSET_X + inset + listWidth + PANE_DIVIDER_WIDTH;
|
|
231
329
|
return {
|
|
232
330
|
list: { y0: headerRow, y1: lastRow, x0: listX0, x1: listX0 + listWidth - 1 },
|
|
233
331
|
preview: { y0: headerRow, y1: lastRow, x0: previewX0, x1: previewX0 + previewWidth - 1 },
|
|
@@ -239,9 +337,9 @@ export function sideBySideBands(headerRow, lastRow, listWidth, previewWidth) {
|
|
|
239
337
|
* Stacked, the panes share the full width and are told apart by rows, so each
|
|
240
338
|
* band spans the content width and takes its own row range.
|
|
241
339
|
*/
|
|
242
|
-
export function stackedBands(listRows, previewRows, innerWidth) {
|
|
243
|
-
const x0 = CONTENT_INSET_X;
|
|
244
|
-
const x1 =
|
|
340
|
+
export function stackedBands(listRows, previewRows, innerWidth, inset = 0) {
|
|
341
|
+
const x0 = CONTENT_INSET_X + inset;
|
|
342
|
+
const x1 = x0 + innerWidth - 1;
|
|
245
343
|
return {
|
|
246
344
|
list: { y0: listRows.top, y1: listRows.bottom, x0, x1 },
|
|
247
345
|
preview: { y0: previewRows.top, y1: previewRows.bottom, x0, x1 },
|
|
@@ -33,6 +33,8 @@ export interface QuestionnaireData {
|
|
|
33
33
|
title?: string;
|
|
34
34
|
questions: QuestionnaireQuestion[];
|
|
35
35
|
allowOther?: boolean;
|
|
36
|
+
/** Show an optional prompt-style note beneath select options. Used by ask_user. */
|
|
37
|
+
allowOptionNotes?: boolean;
|
|
36
38
|
callback: (answers: Record<string, string | string[]> | null) => void | Promise<void>;
|
|
37
39
|
}
|
|
38
40
|
export interface QuestionnaireSurface {
|
|
@@ -50,6 +52,8 @@ export declare class QuestionnaireWidget {
|
|
|
50
52
|
private otherMode;
|
|
51
53
|
private otherValue;
|
|
52
54
|
private textValues;
|
|
55
|
+
private optionNotes;
|
|
56
|
+
private editingOptionNote;
|
|
53
57
|
constructor(host: WidgetHost);
|
|
54
58
|
/** Index of the option the agent flagged as recommended, or -1 when there is none. */
|
|
55
59
|
private static recommendedOptionIndex;
|
|
@@ -57,6 +61,10 @@ export declare class QuestionnaireWidget {
|
|
|
57
61
|
cancel(): void;
|
|
58
62
|
isActive(): boolean;
|
|
59
63
|
private goToQuestion;
|
|
64
|
+
private getOptionNote;
|
|
65
|
+
private setOptionNote;
|
|
66
|
+
private selectHighlightedOption;
|
|
67
|
+
private saveOptionNotes;
|
|
60
68
|
private submitAnswers;
|
|
61
69
|
private advanceOrSubmit;
|
|
62
70
|
/**
|
|
@@ -66,6 +74,7 @@ export declare class QuestionnaireWidget {
|
|
|
66
74
|
* key is not a delete key.
|
|
67
75
|
*/
|
|
68
76
|
private applyDeleteKey;
|
|
77
|
+
private handleOptionNoteInput;
|
|
69
78
|
handleInput(input: string, key: KeyEvent): void;
|
|
70
79
|
/**
|
|
71
80
|
* Styled rows for the form plus the plain-text view of those same rows.
|