@duetso/agent 0.1.81 → 0.1.82
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/dist/package.json +1 -1
- package/dist/src/memory/observational.d.ts +7 -0
- package/dist/src/memory/observational.d.ts.map +1 -1
- package/dist/src/memory/observational.js +7 -1
- package/dist/src/memory/observational.js.map +1 -1
- package/dist/src/tui/app.d.ts +25 -35
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +195 -2308
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/tui/autocomplete-controller.d.ts +83 -0
- package/dist/src/tui/autocomplete-controller.d.ts.map +1 -0
- package/dist/src/tui/autocomplete-controller.js +308 -0
- package/dist/src/tui/autocomplete-controller.js.map +1 -0
- package/dist/src/tui/boot-screen.d.ts +64 -0
- package/dist/src/tui/boot-screen.d.ts.map +1 -0
- package/dist/src/tui/boot-screen.js +137 -0
- package/dist/src/tui/boot-screen.js.map +1 -0
- package/dist/src/tui/controllers.d.ts +39 -0
- package/dist/src/tui/controllers.d.ts.map +1 -0
- package/dist/src/tui/controllers.js +53 -0
- package/dist/src/tui/controllers.js.map +1 -0
- package/dist/src/tui/copy-controller.d.ts +75 -0
- package/dist/src/tui/copy-controller.d.ts.map +1 -0
- package/dist/src/tui/copy-controller.js +140 -0
- package/dist/src/tui/copy-controller.js.map +1 -0
- package/dist/src/tui/history-replay.d.ts +33 -0
- package/dist/src/tui/history-replay.d.ts.map +1 -0
- package/dist/src/tui/history-replay.js +47 -0
- package/dist/src/tui/history-replay.js.map +1 -0
- package/dist/src/tui/initial-prompt.d.ts +24 -0
- package/dist/src/tui/initial-prompt.d.ts.map +1 -0
- package/dist/src/tui/initial-prompt.js +29 -0
- package/dist/src/tui/initial-prompt.js.map +1 -0
- package/dist/src/tui/key-handlers.d.ts +49 -0
- package/dist/src/tui/key-handlers.d.ts.map +1 -0
- package/dist/src/tui/key-handlers.js +192 -0
- package/dist/src/tui/key-handlers.js.map +1 -0
- package/dist/src/tui/layout.d.ts +71 -0
- package/dist/src/tui/layout.d.ts.map +1 -0
- package/dist/src/tui/layout.js +245 -0
- package/dist/src/tui/layout.js.map +1 -0
- package/dist/src/tui/paste-controller.d.ts +90 -0
- package/dist/src/tui/paste-controller.d.ts.map +1 -0
- package/dist/src/tui/paste-controller.js +234 -0
- package/dist/src/tui/paste-controller.js.map +1 -0
- package/dist/src/tui/question-picker.d.ts +111 -0
- package/dist/src/tui/question-picker.d.ts.map +1 -0
- package/dist/src/tui/question-picker.js +308 -0
- package/dist/src/tui/question-picker.js.map +1 -0
- package/dist/src/tui/renderer-lifecycle.d.ts +20 -0
- package/dist/src/tui/renderer-lifecycle.d.ts.map +1 -0
- package/dist/src/tui/renderer-lifecycle.js +50 -0
- package/dist/src/tui/renderer-lifecycle.js.map +1 -0
- package/dist/src/tui/session-subscription.d.ts +30 -0
- package/dist/src/tui/session-subscription.d.ts.map +1 -0
- package/dist/src/tui/session-subscription.js +78 -0
- package/dist/src/tui/session-subscription.js.map +1 -0
- package/dist/src/tui/slash-commands.d.ts +23 -0
- package/dist/src/tui/slash-commands.d.ts.map +1 -0
- package/dist/src/tui/slash-commands.js +79 -0
- package/dist/src/tui/slash-commands.js.map +1 -0
- package/dist/src/tui/starter-section.d.ts +99 -0
- package/dist/src/tui/starter-section.d.ts.map +1 -0
- package/dist/src/tui/starter-section.js +254 -0
- package/dist/src/tui/starter-section.js.map +1 -0
- package/dist/src/tui/status-controller.d.ts +94 -0
- package/dist/src/tui/status-controller.d.ts.map +1 -0
- package/dist/src/tui/status-controller.js +186 -0
- package/dist/src/tui/status-controller.js.map +1 -0
- package/dist/src/tui/step-renderer.d.ts +55 -0
- package/dist/src/tui/step-renderer.d.ts.map +1 -0
- package/dist/src/tui/step-renderer.js +246 -0
- package/dist/src/tui/step-renderer.js.map +1 -0
- package/dist/src/tui/transcript-writer.d.ts +63 -0
- package/dist/src/tui/transcript-writer.d.ts.map +1 -0
- package/dist/src/tui/transcript-writer.js +130 -0
- package/dist/src/tui/transcript-writer.js.map +1 -0
- package/dist/src/turn-runner/turn-runner.d.ts +43 -1
- package/dist/src/turn-runner/turn-runner.d.ts.map +1 -1
- package/dist/src/turn-runner/turn-runner.js +86 -4
- package/dist/src/turn-runner/turn-runner.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { fg, t, } from "@opentui/core";
|
|
2
|
+
import { AUTOCOMPLETE_LIMITS, commitActiveAnswer, formatQuestionOptionDescription, moveQuestionHighlight, NO_HIGHLIGHT, restoreSavedAnswer, } from "./autocomplete.js";
|
|
3
|
+
import { COLORS } from "./theme.js";
|
|
4
|
+
const QUESTION_OPTION_LIMIT = AUTOCOMPLETE_LIMITS.questionOption;
|
|
5
|
+
/**
|
|
6
|
+
* Owns the question picker: an ask terminal hands it a list of
|
|
7
|
+
* `TurnQuestion`s and the picker walks the user through them, accumulating
|
|
8
|
+
* selected option labels until the user either finishes the last question
|
|
9
|
+
* (dispatches an `answer`), types a free-form prompt over the top
|
|
10
|
+
* (`flushWithMessage`), or escapes out (host suppresses next escape so the
|
|
11
|
+
* TUI doesn't also exit).
|
|
12
|
+
*
|
|
13
|
+
* Single-select questions live-record the highlighted option as the answer
|
|
14
|
+
* so arrow navigation alone is enough; multi-select keeps the highlight
|
|
15
|
+
* separate from a checked-set toggled via Space/Enter and grows a synthetic
|
|
16
|
+
* "Done" row that advances to the next question.
|
|
17
|
+
*/
|
|
18
|
+
export class QuestionPicker {
|
|
19
|
+
opts;
|
|
20
|
+
pendingQuestions = [];
|
|
21
|
+
activeIndex = 0;
|
|
22
|
+
// `NO_HIGHLIGHT` (-1) means no row is highlighted yet — the user must press
|
|
23
|
+
// Up/Down to land on a concrete row. Single-select live-records the
|
|
24
|
+
// highlight as the answer; multi-select uses highlight purely for
|
|
25
|
+
// navigation and toggles the checked set on Space/Enter.
|
|
26
|
+
optionSelectedIndex = NO_HIGHLIGHT;
|
|
27
|
+
// Per-question checked indices for the active multi-select question. Reset
|
|
28
|
+
// when the picker advances to the next question; single-select questions
|
|
29
|
+
// simply ignore this set and use `optionSelectedIndex` instead.
|
|
30
|
+
multiSelectChecked = new Set();
|
|
31
|
+
// Answers collected while walking the picker, keyed by question text. We
|
|
32
|
+
// dispatch the full map once the user finishes the last question, or flush
|
|
33
|
+
// it early when they decide to type a free-form prompt instead.
|
|
34
|
+
accumulatedAnswers = {};
|
|
35
|
+
constructor(opts) {
|
|
36
|
+
this.opts = opts;
|
|
37
|
+
}
|
|
38
|
+
isOpen() {
|
|
39
|
+
const question = this.pendingQuestions[this.activeIndex];
|
|
40
|
+
return Boolean(question && question.options.length > 0);
|
|
41
|
+
}
|
|
42
|
+
show(questions) {
|
|
43
|
+
this.pendingQuestions = questions;
|
|
44
|
+
this.activeIndex = 0;
|
|
45
|
+
this.optionSelectedIndex = NO_HIGHLIGHT;
|
|
46
|
+
this.multiSelectChecked = new Set();
|
|
47
|
+
this.accumulatedAnswers = {};
|
|
48
|
+
this.render();
|
|
49
|
+
}
|
|
50
|
+
hide() {
|
|
51
|
+
this.pendingQuestions = [];
|
|
52
|
+
this.activeIndex = 0;
|
|
53
|
+
this.optionSelectedIndex = NO_HIGHLIGHT;
|
|
54
|
+
this.multiSelectChecked = new Set();
|
|
55
|
+
this.accumulatedAnswers = {};
|
|
56
|
+
this.opts.questionPanel.visible = false;
|
|
57
|
+
for (const row of this.opts.questionRows) {
|
|
58
|
+
row.visible = false;
|
|
59
|
+
row.content = "";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Confirm whatever is currently highlighted. Multi-select on a regular row
|
|
64
|
+
* toggles; multi-select on the Done row advances. Single-select always
|
|
65
|
+
* advances (highlight = answer is already live-recorded by Up/Down). No-op
|
|
66
|
+
* when nothing is highlighted yet so the user is forced to make an
|
|
67
|
+
* explicit choice (or skip via Right-arrow).
|
|
68
|
+
*/
|
|
69
|
+
confirmSelection() {
|
|
70
|
+
const question = this.activeQuestion();
|
|
71
|
+
if (!question)
|
|
72
|
+
return false;
|
|
73
|
+
if (this.optionSelectedIndex === NO_HIGHLIGHT)
|
|
74
|
+
return false;
|
|
75
|
+
if (question.multiSelect && this.optionSelectedIndex !== this.activeQuestionDoneIndex()) {
|
|
76
|
+
this.toggleActiveMultiSelectOption();
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return this.advanceOrSubmit();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Dispatch the partially-collected answers together with a free-form
|
|
83
|
+
* `message` (and any pending image attachments) as a single
|
|
84
|
+
* `session.answer({ ..., message, images })` turn, then hide the picker.
|
|
85
|
+
* Used when the user types over the top of an open picker — without this
|
|
86
|
+
* the partial selections would be discarded when the prompt fires.
|
|
87
|
+
*/
|
|
88
|
+
flushWithMessage(message, images) {
|
|
89
|
+
void this.opts.session
|
|
90
|
+
.answer({
|
|
91
|
+
questions: this.pendingQuestions,
|
|
92
|
+
answers: this.accumulatedAnswers,
|
|
93
|
+
behavior: "follow_up",
|
|
94
|
+
message,
|
|
95
|
+
images,
|
|
96
|
+
})
|
|
97
|
+
.catch(this.opts.reportError);
|
|
98
|
+
this.hide();
|
|
99
|
+
if (!this.opts.isRunning())
|
|
100
|
+
this.opts.markRunning();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Handle a keystroke while the picker is open. Returns `true` if the key
|
|
104
|
+
* was claimed (and `key.preventDefault()` already called); the caller
|
|
105
|
+
* should stop further dispatch in that case. Returns `false` when the
|
|
106
|
+
* picker is closed or the key isn't one this controller handles.
|
|
107
|
+
*/
|
|
108
|
+
handleKey(key) {
|
|
109
|
+
if (!this.isOpen())
|
|
110
|
+
return false;
|
|
111
|
+
if (key.name === "up") {
|
|
112
|
+
this.moveActiveHighlight(-1);
|
|
113
|
+
key.preventDefault();
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (key.name === "down") {
|
|
117
|
+
this.moveActiveHighlight(1);
|
|
118
|
+
key.preventDefault();
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
// Space confirms the active selection only when the composer is empty
|
|
122
|
+
// so users can still type a free-form prompt that includes spaces.
|
|
123
|
+
// Match either the named form (most terminals) or the literal-char
|
|
124
|
+
// form some kitty-keyboard parsers emit so the binding is robust
|
|
125
|
+
// regardless of how the host reports an unmodified Space.
|
|
126
|
+
if ((key.name === "space" || key.name === " ") && this.opts.inputField.plainText.length === 0) {
|
|
127
|
+
key.preventDefault();
|
|
128
|
+
this.confirmSelection();
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
// Left/Right navigate between questions, but only when the composer is
|
|
132
|
+
// empty so editing a typed prompt with arrow keys still works.
|
|
133
|
+
if ((key.name === "left" || key.name === "right") &&
|
|
134
|
+
this.opts.inputField.plainText.length === 0 &&
|
|
135
|
+
this.pendingQuestions.length > 1) {
|
|
136
|
+
const direction = key.name === "left" ? -1 : 1;
|
|
137
|
+
if (this.navigateActive(direction)) {
|
|
138
|
+
key.preventDefault();
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (key.name === "escape") {
|
|
143
|
+
key.preventDefault();
|
|
144
|
+
this.opts.onEscapeClose();
|
|
145
|
+
this.hide();
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
// ---- internal -----------------------------------------------------------
|
|
151
|
+
activeQuestion() {
|
|
152
|
+
return this.pendingQuestions[this.activeIndex];
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Total navigable rows for the active question. The Up/Down handler clamps
|
|
156
|
+
* navigation to what is actually rendered on screen so a user cannot land
|
|
157
|
+
* the highlight on a row they cannot see.
|
|
158
|
+
*/
|
|
159
|
+
activeRowCount() {
|
|
160
|
+
const question = this.activeQuestion();
|
|
161
|
+
if (!question)
|
|
162
|
+
return 0;
|
|
163
|
+
const optionLimit = question.multiSelect ? QUESTION_OPTION_LIMIT - 1 : QUESTION_OPTION_LIMIT;
|
|
164
|
+
const visibleOptionCount = Math.min(question.options.length, optionLimit);
|
|
165
|
+
return visibleOptionCount + (question.multiSelect ? 1 : 0);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Row index of the synthetic Done row when the active question is
|
|
169
|
+
* multi-select; `undefined` otherwise so callers don't compare against a
|
|
170
|
+
* sentinel value. The Done row sits one past the last visible option,
|
|
171
|
+
* clamped to the same limit `render()` uses.
|
|
172
|
+
*/
|
|
173
|
+
activeQuestionDoneIndex() {
|
|
174
|
+
const question = this.activeQuestion();
|
|
175
|
+
if (!question?.multiSelect)
|
|
176
|
+
return undefined;
|
|
177
|
+
const optionLimit = QUESTION_OPTION_LIMIT - 1;
|
|
178
|
+
return Math.min(question.options.length, optionLimit);
|
|
179
|
+
}
|
|
180
|
+
render() {
|
|
181
|
+
const question = this.activeQuestion();
|
|
182
|
+
if (!question || question.options.length === 0) {
|
|
183
|
+
this.hide();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const { questionPanel, questionTitle, questionRows } = this.opts;
|
|
187
|
+
questionPanel.visible = true;
|
|
188
|
+
const baseTitle = question.header
|
|
189
|
+
? `${question.header}: ${question.question}`
|
|
190
|
+
: question.question;
|
|
191
|
+
const positionPrefix = this.pendingQuestions.length > 1
|
|
192
|
+
? `(${this.activeIndex + 1}/${this.pendingQuestions.length}) `
|
|
193
|
+
: "";
|
|
194
|
+
const navHint = this.pendingQuestions.length > 1 ? " [←/→ navigate]" : "";
|
|
195
|
+
questionTitle.content = `${positionPrefix}${baseTitle}${navHint}`;
|
|
196
|
+
const optionLimit = question.multiSelect ? QUESTION_OPTION_LIMIT - 1 : QUESTION_OPTION_LIMIT;
|
|
197
|
+
const visibleOptions = question.options.slice(0, optionLimit);
|
|
198
|
+
const doneIndex = this.activeQuestionDoneIndex();
|
|
199
|
+
for (const [index, row] of questionRows.entries()) {
|
|
200
|
+
if (index < visibleOptions.length) {
|
|
201
|
+
const option = visibleOptions[index];
|
|
202
|
+
const highlighted = index === this.optionSelectedIndex;
|
|
203
|
+
const checkbox = question.multiSelect
|
|
204
|
+
? this.multiSelectChecked.has(index)
|
|
205
|
+
? "[x] "
|
|
206
|
+
: "[ ] "
|
|
207
|
+
: "";
|
|
208
|
+
const labelColor = highlighted ? COLORS.status : COLORS.user;
|
|
209
|
+
const description = formatQuestionOptionDescription(option.description);
|
|
210
|
+
const labelLine = `${checkbox}${option.label}`;
|
|
211
|
+
row.content = description
|
|
212
|
+
? t `${fg(labelColor)(labelLine)}\n${description}`
|
|
213
|
+
: t `${fg(labelColor)(labelLine)}`;
|
|
214
|
+
row.fg = highlighted ? COLORS.agent : COLORS.hint;
|
|
215
|
+
row.visible = true;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (question.multiSelect && index === visibleOptions.length) {
|
|
219
|
+
// Synthetic Done row carries no checkbox prefix and self-documents
|
|
220
|
+
// its purpose so users discover how to advance from a multi-select.
|
|
221
|
+
const highlighted = doneIndex === this.optionSelectedIndex;
|
|
222
|
+
const labelColor = highlighted ? COLORS.status : COLORS.user;
|
|
223
|
+
const description = formatQuestionOptionDescription("Advance to next question");
|
|
224
|
+
row.content = t `${fg(labelColor)("Done")}\n${description}`;
|
|
225
|
+
row.fg = highlighted ? COLORS.agent : COLORS.hint;
|
|
226
|
+
row.visible = true;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
row.visible = false;
|
|
230
|
+
row.content = "";
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
moveActiveHighlight(direction) {
|
|
234
|
+
const question = this.activeQuestion();
|
|
235
|
+
if (!question)
|
|
236
|
+
return;
|
|
237
|
+
this.optionSelectedIndex = moveQuestionHighlight(this.optionSelectedIndex, this.activeRowCount(), direction);
|
|
238
|
+
// Single-select live-records the highlight as the answer so a
|
|
239
|
+
// prompt-flush or arrow-nav captures it without requiring Space/Enter.
|
|
240
|
+
// Multi-select keeps highlight separate from the toggled set.
|
|
241
|
+
if (!question.multiSelect) {
|
|
242
|
+
this.accumulatedAnswers = commitActiveAnswer(question, this.optionSelectedIndex, this.multiSelectChecked, this.accumulatedAnswers);
|
|
243
|
+
}
|
|
244
|
+
this.render();
|
|
245
|
+
}
|
|
246
|
+
toggleActiveMultiSelectOption() {
|
|
247
|
+
const question = this.activeQuestion();
|
|
248
|
+
if (!question?.multiSelect)
|
|
249
|
+
return;
|
|
250
|
+
if (this.multiSelectChecked.has(this.optionSelectedIndex)) {
|
|
251
|
+
this.multiSelectChecked.delete(this.optionSelectedIndex);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
this.multiSelectChecked.add(this.optionSelectedIndex);
|
|
255
|
+
}
|
|
256
|
+
this.accumulatedAnswers = commitActiveAnswer(question, this.optionSelectedIndex, this.multiSelectChecked, this.accumulatedAnswers);
|
|
257
|
+
this.render();
|
|
258
|
+
}
|
|
259
|
+
navigateActive(direction) {
|
|
260
|
+
if (this.pendingQuestions.length <= 1)
|
|
261
|
+
return false;
|
|
262
|
+
const nextIndex = this.activeIndex + direction;
|
|
263
|
+
if (nextIndex < 0 || nextIndex >= this.pendingQuestions.length)
|
|
264
|
+
return false;
|
|
265
|
+
this.accumulatedAnswers = commitActiveAnswer(this.activeQuestion(), this.optionSelectedIndex, this.multiSelectChecked, this.accumulatedAnswers);
|
|
266
|
+
this.activeIndex = nextIndex;
|
|
267
|
+
const restored = restoreSavedAnswer(this.activeQuestion(), this.accumulatedAnswers);
|
|
268
|
+
this.optionSelectedIndex = restored.selectedIndex;
|
|
269
|
+
this.multiSelectChecked = restored.checked;
|
|
270
|
+
this.render();
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
describeAnswerLabels(question, labels) {
|
|
274
|
+
if (labels.length === 0)
|
|
275
|
+
return question.multiSelect ? "(no selection)" : "";
|
|
276
|
+
return labels.join(", ");
|
|
277
|
+
}
|
|
278
|
+
advanceOrSubmit() {
|
|
279
|
+
const question = this.activeQuestion();
|
|
280
|
+
if (!question)
|
|
281
|
+
return false;
|
|
282
|
+
const accumulatedForActive = this.accumulatedAnswers[question.question] ?? [];
|
|
283
|
+
const transcriptText = this.describeAnswerLabels(question, accumulatedForActive);
|
|
284
|
+
if (transcriptText) {
|
|
285
|
+
this.opts.recordTranscriptEntry("user", transcriptText);
|
|
286
|
+
this.opts.appendBlock("you:", transcriptText, COLORS.user);
|
|
287
|
+
}
|
|
288
|
+
if (this.activeIndex < this.pendingQuestions.length - 1) {
|
|
289
|
+
this.activeIndex += 1;
|
|
290
|
+
const restored = restoreSavedAnswer(this.activeQuestion(), this.accumulatedAnswers);
|
|
291
|
+
this.optionSelectedIndex = restored.selectedIndex;
|
|
292
|
+
this.multiSelectChecked = restored.checked;
|
|
293
|
+
this.render();
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
void this.opts.session
|
|
297
|
+
.answer({
|
|
298
|
+
questions: this.pendingQuestions,
|
|
299
|
+
answers: this.accumulatedAnswers,
|
|
300
|
+
behavior: "follow_up",
|
|
301
|
+
})
|
|
302
|
+
.catch(this.opts.reportError);
|
|
303
|
+
this.hide();
|
|
304
|
+
this.opts.markRunning();
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=question-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"question-picker.js","sourceRoot":"","sources":["../../../src/tui/question-picker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type CliRenderer } from "@opentui/core";
|
|
2
|
+
/**
|
|
3
|
+
* useMouse: true so the scroll wheel reaches the transcript and OpenTUI
|
|
4
|
+
* receives drag events for in-app text selection. Bare Ctrl+C is the
|
|
5
|
+
* always-exit keystroke (via exitOnCtrlC) so the convention every other
|
|
6
|
+
* interactive Linux/Windows terminal app follows still works here.
|
|
7
|
+
*
|
|
8
|
+
* Tests inject a `createTestRenderer` instance via `input.renderer`; in
|
|
9
|
+
* that mode we skip the production renderer construction and the
|
|
10
|
+
* `globalThis.window` restore that wraps it (the test renderer never
|
|
11
|
+
* installs the shim).
|
|
12
|
+
*/
|
|
13
|
+
export declare function acquireRenderer(injected?: CliRenderer): Promise<CliRenderer>;
|
|
14
|
+
/**
|
|
15
|
+
* Resolves when the renderer emits its `destroy` event, running the supplied
|
|
16
|
+
* teardown hook synchronously inside the event listener so chrome writers can
|
|
17
|
+
* flip into a stopped state before the rest of `runTui` returns.
|
|
18
|
+
*/
|
|
19
|
+
export declare function waitForRendererDestroy(renderer: CliRenderer, onDestroy: () => void): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=renderer-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/tui/renderer-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,eAAe,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAWlF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,MAAM,IAAI,GACpB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createCliRenderer } from "@opentui/core";
|
|
2
|
+
/**
|
|
3
|
+
* useMouse: true so the scroll wheel reaches the transcript and OpenTUI
|
|
4
|
+
* receives drag events for in-app text selection. Bare Ctrl+C is the
|
|
5
|
+
* always-exit keystroke (via exitOnCtrlC) so the convention every other
|
|
6
|
+
* interactive Linux/Windows terminal app follows still works here.
|
|
7
|
+
*
|
|
8
|
+
* Tests inject a `createTestRenderer` instance via `input.renderer`; in
|
|
9
|
+
* that mode we skip the production renderer construction and the
|
|
10
|
+
* `globalThis.window` restore that wraps it (the test renderer never
|
|
11
|
+
* installs the shim).
|
|
12
|
+
*/
|
|
13
|
+
export async function acquireRenderer(injected) {
|
|
14
|
+
if (injected)
|
|
15
|
+
return injected;
|
|
16
|
+
const previousWindow = Object.getOwnPropertyDescriptor(globalThis, "window");
|
|
17
|
+
const renderer = await createCliRenderer({
|
|
18
|
+
exitOnCtrlC: true,
|
|
19
|
+
useMouse: true,
|
|
20
|
+
useKittyKeyboard: {},
|
|
21
|
+
targetFps: 60,
|
|
22
|
+
});
|
|
23
|
+
restoreWindowGlobal(previousWindow);
|
|
24
|
+
return renderer;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolves when the renderer emits its `destroy` event, running the supplied
|
|
28
|
+
* teardown hook synchronously inside the event listener so chrome writers can
|
|
29
|
+
* flip into a stopped state before the rest of `runTui` returns.
|
|
30
|
+
*/
|
|
31
|
+
export function waitForRendererDestroy(renderer, onDestroy) {
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
renderer.once("destroy", () => {
|
|
34
|
+
onDestroy();
|
|
35
|
+
resolve();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function restoreWindowGlobal(previousWindow) {
|
|
40
|
+
// OpenTUI installs `window.requestAnimationFrame` for browser-style
|
|
41
|
+
// animation compatibility. In Bun, the presence of `window` can send fetch
|
|
42
|
+
// internals down browser-only paths, while `global.requestAnimationFrame`
|
|
43
|
+
// remains enough for OpenTUI after initialization.
|
|
44
|
+
if (previousWindow) {
|
|
45
|
+
Object.defineProperty(globalThis, "window", previousWindow);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
delete globalThis.window;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=renderer-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer-lifecycle.js","sourceRoot":"","sources":["../../../src/tui/renderer-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAsB;IAC1D,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,cAAc,GAAG,MAAM,CAAC,wBAAwB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC;QACvC,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,IAAI;QACd,gBAAgB,EAAE,EAAE;QACpB,SAAS,EAAE,EAAE;KACd,CAAC,CAAC;IACH,mBAAmB,CAAC,cAAc,CAAC,CAAC;IACpC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAqB,EACrB,SAAqB;IAErB,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;YAC5B,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,cAA8C;IACzE,oEAAoE;IACpE,2EAA2E;IAC3E,0EAA0E;IAC1E,mDAAmD;IACnD,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IACD,OAAQ,UAAuD,CAAC,MAAM,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Session } from "../session/session.js";
|
|
2
|
+
import type { QuestionPicker } from "./question-picker.js";
|
|
3
|
+
import type { Sidebar } from "./sidebar.js";
|
|
4
|
+
import type { StatusController } from "./status-controller.js";
|
|
5
|
+
import type { StepRenderer } from "./step-renderer.js";
|
|
6
|
+
export interface SessionSubscriptionDeps {
|
|
7
|
+
session: Session;
|
|
8
|
+
sidebar: Sidebar;
|
|
9
|
+
stepRenderer: StepRenderer;
|
|
10
|
+
statusController: StatusController;
|
|
11
|
+
questionPicker: QuestionPicker;
|
|
12
|
+
appendLine(content: string, fg: string): void;
|
|
13
|
+
appendBlock(label: string | null, body: string, fg: string): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Re-paints the sidebar from the session's current state snapshot. Used both
|
|
17
|
+
* inside the event subscription and after the initial boot screen renders.
|
|
18
|
+
*/
|
|
19
|
+
export declare function refreshSidebarFromSession(deps: {
|
|
20
|
+
session: Session;
|
|
21
|
+
sidebar: Sidebar;
|
|
22
|
+
}): void;
|
|
23
|
+
/**
|
|
24
|
+
* Subscribes the chrome (transcript, sidebar, status, question picker) to the
|
|
25
|
+
* session's event stream and returns the unsubscribe handle. Every event the
|
|
26
|
+
* runner emits funnels through this one router so the visual layer stays a
|
|
27
|
+
* thin projection of the session state.
|
|
28
|
+
*/
|
|
29
|
+
export declare function bindSessionToUi(deps: SessionSubscriptionDeps): () => void;
|
|
30
|
+
//# sourceMappingURL=session-subscription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-subscription.d.ts","sourceRoot":"","sources":["../../../src/tui/session-subscription.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACnE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAkB5F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,IAAI,CAgDzE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { COLORS } from "./theme.js";
|
|
2
|
+
/**
|
|
3
|
+
* Re-paints the sidebar from the session's current state snapshot. Used both
|
|
4
|
+
* inside the event subscription and after the initial boot screen renders.
|
|
5
|
+
*/
|
|
6
|
+
export function refreshSidebarFromSession(deps) {
|
|
7
|
+
const { session, sidebar } = deps;
|
|
8
|
+
const state = session.getState();
|
|
9
|
+
sidebar.setTodos(state?.todos ?? []);
|
|
10
|
+
sidebar.setFollowUpQueue(state?.followUpQueue ?? []);
|
|
11
|
+
sidebar.setStateMachine(state?.stateMachine);
|
|
12
|
+
const snap = session.getLastUsage();
|
|
13
|
+
sidebar.setUsage(snap
|
|
14
|
+
? {
|
|
15
|
+
type: "usage",
|
|
16
|
+
usage: snap.usage,
|
|
17
|
+
effectiveContextWindow: snap.effectiveContextWindow,
|
|
18
|
+
contextWindowUsage: snap.contextWindowUsage,
|
|
19
|
+
}
|
|
20
|
+
: undefined);
|
|
21
|
+
sidebar.setSessionCost(session.getSessionCostUsd());
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Subscribes the chrome (transcript, sidebar, status, question picker) to the
|
|
25
|
+
* session's event stream and returns the unsubscribe handle. Every event the
|
|
26
|
+
* runner emits funnels through this one router so the visual layer stays a
|
|
27
|
+
* thin projection of the session state.
|
|
28
|
+
*/
|
|
29
|
+
export function bindSessionToUi(deps) {
|
|
30
|
+
const { session, sidebar, stepRenderer, statusController, questionPicker, appendLine, appendBlock, } = deps;
|
|
31
|
+
const refreshSidebar = () => refreshSidebarFromSession({ session, sidebar });
|
|
32
|
+
return session.subscribe((event) => {
|
|
33
|
+
refreshSidebar();
|
|
34
|
+
if (event.type === "step") {
|
|
35
|
+
stepRenderer.renderStep(event.step);
|
|
36
|
+
}
|
|
37
|
+
else if (event.type === "follow_up_queue") {
|
|
38
|
+
// Mirror the count into the working-status line so the user can see
|
|
39
|
+
// queued prompts at a glance without scrolling the sidebar.
|
|
40
|
+
statusController.setQueuedFollowUps(event.prompts.length);
|
|
41
|
+
}
|
|
42
|
+
else if (event.type === "memory") {
|
|
43
|
+
stepRenderer.renderMemoryStatus(event);
|
|
44
|
+
}
|
|
45
|
+
else if (event.type === "system") {
|
|
46
|
+
appendBlock("[system]", event.message, COLORS.system);
|
|
47
|
+
if (event.level === "error")
|
|
48
|
+
statusController.markIdle();
|
|
49
|
+
}
|
|
50
|
+
else if (event.type === "ask") {
|
|
51
|
+
appendBlock("[question]", event.questions.map((q) => q.question).join("\n"), COLORS.system);
|
|
52
|
+
questionPicker.show(event.questions);
|
|
53
|
+
stepRenderer.renderUsage(event.usage);
|
|
54
|
+
stepRenderer.renderTurnElapsed();
|
|
55
|
+
statusController.markIdle(event);
|
|
56
|
+
}
|
|
57
|
+
else if (event.type === "complete") {
|
|
58
|
+
if (event.error) {
|
|
59
|
+
appendBlock("[error]", event.error, COLORS.error);
|
|
60
|
+
}
|
|
61
|
+
stepRenderer.renderUsage(event.usage);
|
|
62
|
+
stepRenderer.renderTurnElapsed();
|
|
63
|
+
statusController.markIdle(event);
|
|
64
|
+
}
|
|
65
|
+
else if (event.type === "interrupted") {
|
|
66
|
+
appendLine("[interrupted]", COLORS.system);
|
|
67
|
+
stepRenderer.renderUsage(event.usage);
|
|
68
|
+
stepRenderer.renderTurnElapsed();
|
|
69
|
+
statusController.markIdle(event);
|
|
70
|
+
}
|
|
71
|
+
else if (event.type === "sleep") {
|
|
72
|
+
stepRenderer.renderUsage(event.usage);
|
|
73
|
+
stepRenderer.renderSleeping(event.wakeAt);
|
|
74
|
+
statusController.markIdle(event);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=session-subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-subscription.js","sourceRoot":"","sources":["../../../src/tui/session-subscription.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CopyController } from "./copy-controller.js";
|
|
2
|
+
import type { PasteController } from "./paste-controller.js";
|
|
3
|
+
import type { TranscriptWriter } from "./transcript-writer.js";
|
|
4
|
+
/**
|
|
5
|
+
* Surface used by the slash-command dispatcher. Every handler in this module
|
|
6
|
+
* is stateless and reaches its mutable state through the controllers wired up
|
|
7
|
+
* by `runTui`. The dispatcher returns true when the message was claimed so
|
|
8
|
+
* `submit()` can short-circuit before the message reaches `session.prompt()`.
|
|
9
|
+
*/
|
|
10
|
+
export interface SlashCommandContext {
|
|
11
|
+
pasteController: PasteController;
|
|
12
|
+
copyController: CopyController;
|
|
13
|
+
transcriptWriter: TranscriptWriter;
|
|
14
|
+
appendBlock(label: string | null, body: string, fg: string): void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Routes the message to a local handler when it begins with a slash command
|
|
18
|
+
* recognized by the TUI. Returns true when handled (caller must not forward
|
|
19
|
+
* the message to the runner) and false when the message should fall through
|
|
20
|
+
* to the normal prompt path.
|
|
21
|
+
*/
|
|
22
|
+
export declare function tryDispatchSlashCommand(message: string, ctx: SlashCommandContext): boolean;
|
|
23
|
+
//# sourceMappingURL=slash-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slash-commands.d.ts","sourceRoot":"","sources":["../../../src/tui/slash-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI/D;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,eAAe,CAAC;IACjC,cAAc,EAAE,cAAc,CAAC;IAC/B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACnE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CA2B1F"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { submitDuetFeedback } from "../lib/feedback.js";
|
|
2
|
+
import { COLORS } from "./theme.js";
|
|
3
|
+
/**
|
|
4
|
+
* Routes the message to a local handler when it begins with a slash command
|
|
5
|
+
* recognized by the TUI. Returns true when handled (caller must not forward
|
|
6
|
+
* the message to the runner) and false when the message should fall through
|
|
7
|
+
* to the normal prompt path.
|
|
8
|
+
*/
|
|
9
|
+
export function tryDispatchSlashCommand(message, ctx) {
|
|
10
|
+
if (message.startsWith("/image ") || message === "/image") {
|
|
11
|
+
void handleImageSlashCommand(message, ctx);
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
if (message === "/paste") {
|
|
15
|
+
void ctx.pasteController.triggerClipboardProbe("slash");
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (message === "/clear-images") {
|
|
19
|
+
ctx.pasteController.clearPendingImages();
|
|
20
|
+
ctx.appendBlock("[paste]", "cleared pending image attachments", COLORS.system);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (message === "/copy" || message.startsWith("/copy ")) {
|
|
24
|
+
void ctx.copyController.handleCopySlashCommand(message);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
if (message === "/diag" || message.startsWith("/diag ")) {
|
|
28
|
+
handleDiagSlashCommand(message, ctx);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
if (message === "/feedback" || message.startsWith("/feedback ")) {
|
|
32
|
+
void handleFeedbackSlashCommand(message, ctx);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* `/diag` toggles a key + selection event log so users can show us exactly
|
|
39
|
+
* what their terminal forwards when something silently fails (a keystroke
|
|
40
|
+
* that never reaches the handler, a selection event firing with empty text).
|
|
41
|
+
* Kept as a flag rather than a one-shot capture so we can layer additional
|
|
42
|
+
* diagnostic facets on the same surface without inventing new commands.
|
|
43
|
+
*/
|
|
44
|
+
function handleDiagSlashCommand(raw, ctx) {
|
|
45
|
+
const argument = raw === "/diag" ? "" : raw.slice("/diag ".length).trim();
|
|
46
|
+
if (argument === "" || argument === "keys") {
|
|
47
|
+
const enabled = !ctx.transcriptWriter.isKeyDiagnosticsEnabled();
|
|
48
|
+
ctx.transcriptWriter.setKeyDiagnosticsEnabled(enabled);
|
|
49
|
+
ctx.appendBlock("[diag]", enabled
|
|
50
|
+
? "key + selection event logging ON. Run /diag again to stop."
|
|
51
|
+
: "key + selection event logging OFF.", COLORS.system);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
ctx.appendBlock("[diag]", "Usage: /diag (or /diag keys) — toggles key + selection event logging", COLORS.system);
|
|
55
|
+
}
|
|
56
|
+
async function handleFeedbackSlashCommand(raw, ctx) {
|
|
57
|
+
const content = raw.slice("/feedback".length).trim();
|
|
58
|
+
if (!content) {
|
|
59
|
+
ctx.appendBlock("[feedback]", "Usage: /feedback <message> — send free-form feedback to the Duet team", COLORS.system);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
ctx.appendBlock("[feedback]", "sending…", COLORS.system);
|
|
63
|
+
try {
|
|
64
|
+
const { baseUrl } = await submitDuetFeedback({ content });
|
|
65
|
+
ctx.appendBlock("[feedback]", `Thanks! Feedback sent to ${baseUrl}.`, COLORS.system);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
ctx.appendBlock("[feedback]", error instanceof Error ? error.message : String(error), COLORS.error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function handleImageSlashCommand(raw, ctx) {
|
|
72
|
+
const rest = raw.slice("/image".length).trim();
|
|
73
|
+
if (!rest) {
|
|
74
|
+
ctx.appendBlock("[paste]", "Usage: /image <path> — attach a PNG/JPEG/GIF/WebP from disk", COLORS.system);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
await ctx.pasteController.attachImageFromPath(rest);
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=slash-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../../src/tui/slash-commands.ts"],"names":[],"mappings":"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"}
|