shadok-ai 0.15.4 → 0.15.6
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/detect.d.ts +23 -0
- package/dist/detect.js +155 -56
- package/dist/detect.js.map +1 -1
- package/dist/server.js +43 -2
- package/dist/server.js.map +1 -1
- package/dist/session.js +9 -4
- package/dist/session.js.map +1 -1
- package/dist/tmux.js +6 -2
- package/dist/tmux.js.map +1 -1
- package/dist/usage.d.ts +2 -1
- package/dist/usage.js +22 -14
- package/dist/usage.js.map +1 -1
- package/package.json +1 -1
package/dist/detect.d.ts
CHANGED
|
@@ -80,6 +80,29 @@ export declare function inputHasProbe(screen: string, probe: string): boolean;
|
|
|
80
80
|
* literal text isn't on screen to look for).
|
|
81
81
|
*/
|
|
82
82
|
export declare function inputText(screen: string): string;
|
|
83
|
+
/**
|
|
84
|
+
* The WHOLE input box, not just its first line.
|
|
85
|
+
*
|
|
86
|
+
* `inputText` reads the `❯` line alone, which is everything there is while a
|
|
87
|
+
* prompt fits on one line — and nothing at all once it does not. A prompt that
|
|
88
|
+
* wraps, or one pasted into a box that was ALREADY occupied, puts the rest on
|
|
89
|
+
* continuation lines carrying no `❯`, so the line `inputText` watches stops
|
|
90
|
+
* moving while the box fills up.
|
|
91
|
+
*
|
|
92
|
+
* That blind spot is what turned an ordinary interrupt into "the text never
|
|
93
|
+
* appeared in the input box". Observed on a live pane, 300 ms apart: a prompt
|
|
94
|
+
* submitted and running, then an Escape (the Telegram bridge preempting a turn
|
|
95
|
+
* for the message typed right behind it) — and Claude Code **puts the
|
|
96
|
+
* interrupted prompt back into the box**. The next paste therefore landed under
|
|
97
|
+
* text that was already there, the `❯` line never changed, and six attempts
|
|
98
|
+
* stacked six copies of the message's header in the box while every check
|
|
99
|
+
* reported nothing had arrived.
|
|
100
|
+
*
|
|
101
|
+
* Reading the whole box fixes both halves at once: a paste that landed is
|
|
102
|
+
* visible wherever it landed, and a Ctrl-U that removed ONE line (which is all
|
|
103
|
+
* it removes) shows as progress instead of as a box that will not clear.
|
|
104
|
+
*/
|
|
105
|
+
export declare function boxText(screen: string): string;
|
|
83
106
|
/**
|
|
84
107
|
* Why a screen refused a prompt — named, when the shape is recognisable.
|
|
85
108
|
*
|
package/dist/detect.js
CHANGED
|
@@ -123,6 +123,50 @@ export function inputText(screen) {
|
|
|
123
123
|
}
|
|
124
124
|
return inputLine.replace(/^\s*[❯!]\s*/, "").trim();
|
|
125
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Where the input box ENDS: its bottom border, or — for a screen that carries
|
|
128
|
+
* no frame (a narrow pane, an older render) — the status line under it. That
|
|
129
|
+
* line moves on its own (`⏵⏵ auto mode on · 1 shell · ↓ to manage`), and read
|
|
130
|
+
* as part of the box it would pass for a paste that landed.
|
|
131
|
+
*/
|
|
132
|
+
const BOX_END = /^\s*(?:[─━]{10,}|⏵⏵|⏸|\?\s+for shortcuts)/;
|
|
133
|
+
/**
|
|
134
|
+
* The WHOLE input box, not just its first line.
|
|
135
|
+
*
|
|
136
|
+
* `inputText` reads the `❯` line alone, which is everything there is while a
|
|
137
|
+
* prompt fits on one line — and nothing at all once it does not. A prompt that
|
|
138
|
+
* wraps, or one pasted into a box that was ALREADY occupied, puts the rest on
|
|
139
|
+
* continuation lines carrying no `❯`, so the line `inputText` watches stops
|
|
140
|
+
* moving while the box fills up.
|
|
141
|
+
*
|
|
142
|
+
* That blind spot is what turned an ordinary interrupt into "the text never
|
|
143
|
+
* appeared in the input box". Observed on a live pane, 300 ms apart: a prompt
|
|
144
|
+
* submitted and running, then an Escape (the Telegram bridge preempting a turn
|
|
145
|
+
* for the message typed right behind it) — and Claude Code **puts the
|
|
146
|
+
* interrupted prompt back into the box**. The next paste therefore landed under
|
|
147
|
+
* text that was already there, the `❯` line never changed, and six attempts
|
|
148
|
+
* stacked six copies of the message's header in the box while every check
|
|
149
|
+
* reported nothing had arrived.
|
|
150
|
+
*
|
|
151
|
+
* Reading the whole box fixes both halves at once: a paste that landed is
|
|
152
|
+
* visible wherever it landed, and a Ctrl-U that removed ONE line (which is all
|
|
153
|
+
* it removes) shows as progress instead of as a box that will not clear.
|
|
154
|
+
*/
|
|
155
|
+
export function boxText(screen) {
|
|
156
|
+
const lines = screen.split("\n");
|
|
157
|
+
let start = -1;
|
|
158
|
+
for (let i = 0; i < lines.length; i++) {
|
|
159
|
+
if (lines[i].trimStart().startsWith("❯") || /^!\s/.test(lines[i]))
|
|
160
|
+
start = i;
|
|
161
|
+
}
|
|
162
|
+
if (start === -1)
|
|
163
|
+
return "";
|
|
164
|
+
const out = [lines[start].replace(/^\s*[❯!]\s*/, "")];
|
|
165
|
+
// Everything up to the box's bottom border belongs to the box.
|
|
166
|
+
for (let i = start + 1; i < lines.length && !BOX_END.test(lines[i]); i++)
|
|
167
|
+
out.push(lines[i]);
|
|
168
|
+
return out.join("\n").trim();
|
|
169
|
+
}
|
|
126
170
|
/**
|
|
127
171
|
* Why a screen refused a prompt — named, when the shape is recognisable.
|
|
128
172
|
*
|
|
@@ -145,6 +189,15 @@ export function describeStuckScreen(screen) {
|
|
|
145
189
|
return "the screen is a masked input field (long runs of asterisks), so the pasted text is never readable back";
|
|
146
190
|
if (/^\s*❯\s*\d+\.\s+\S/m.test(screen))
|
|
147
191
|
return "the agent is waiting on a question, not on a prompt — answer it first";
|
|
192
|
+
// Last, because the three above are more specific and a full box is often
|
|
193
|
+
// their consequence rather than their cause. MULTI-LINE only: at rest the box
|
|
194
|
+
// shows the previous message as a one-line suggestion, and blaming that ghost
|
|
195
|
+
// would be the confident wrong answer this function exists to avoid. Text
|
|
196
|
+
// Claude Code put back after an interrupt keeps its ⟦header⟧ line, so it is
|
|
197
|
+
// the multi-line one.
|
|
198
|
+
const box = boxText(screen);
|
|
199
|
+
if (box.includes("\n"))
|
|
200
|
+
return `the input box was not empty — it still held ${box.split("\n").length} lines beginning ${JSON.stringify(box.split("\n")[0].slice(0, 50))}, which is what Claude Code puts back there when a turn is interrupted`;
|
|
148
201
|
return null;
|
|
149
202
|
}
|
|
150
203
|
/**
|
|
@@ -270,15 +323,25 @@ export async function moveToOption(pilot, n) {
|
|
|
270
323
|
* "Landed" means the box DIFFERS from what it showed just before the paste, not
|
|
271
324
|
* that it is non-empty: an empty box is not always blank. Before the first
|
|
272
325
|
* prompt of a session, Claude Code (seen on 2.1.285) fills it with an example —
|
|
273
|
-
* `❯ Try "refactor <filepath>"` — which
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
326
|
+
* `❯ Try "refactor <filepath>"` — which reads like typed text, so "non-empty"
|
|
327
|
+
* was true before anything was pasted, and a paste the TUI dropped was followed
|
|
328
|
+
* by Enter on a box holding nothing. The example also comes back after a
|
|
329
|
+
* Ctrl-U, so "cleared" likewise means "back to that resting state". Comparing
|
|
330
|
+
* with the state read just before is content-agnostic (a collapsed "[Pasted
|
|
331
|
+
* text +N lines]" differs from it as well as the text would) and needs no list
|
|
332
|
+
* of hint strings, which would rot with the next release. The baseline is
|
|
333
|
+
* re-read on every attempt, after the recovery has run, so a retry that pastes
|
|
334
|
+
* the same text again is compared with the box it pastes into.
|
|
335
|
+
*
|
|
336
|
+
* Every one of those reads is `boxText`, the WHOLE box, and that is the
|
|
337
|
+
* difference between this working and the failure it was reported for. With
|
|
338
|
+
* `inputText` — the `❯` line alone — a box that already held something was
|
|
339
|
+
* invisible: the paste landed on a continuation line, the watched line never
|
|
340
|
+
* moved, and the recovery's "is it clear?" compared that same unmoving line and
|
|
341
|
+
* answered yes without clearing anything. Six attempts then stacked six copies
|
|
342
|
+
* of the message's header into the box and the submit failed. Two Telegram
|
|
343
|
+
* messages a second apart is all it takes to get there, because an interrupted
|
|
344
|
+
* prompt is put BACK in the box (see `boxText`).
|
|
282
345
|
*
|
|
283
346
|
* It lives here, next to `idleStep` and `moveToOption`, for the reason those do:
|
|
284
347
|
* it was written twice (node-pty and tmux), and could only be exercised by
|
|
@@ -290,11 +353,68 @@ const MAX_CLEARS = 40;
|
|
|
290
353
|
/** How long one press is given to show. Above the tmux mirror's fast poll
|
|
291
354
|
* (`SCREEN_FAST_MS`), or a press that worked would read as one that did not. */
|
|
292
355
|
const CLEAR_STEP_MS = 400;
|
|
356
|
+
/**
|
|
357
|
+
* Empty the input box, one Ctrl-U at a time.
|
|
358
|
+
*
|
|
359
|
+
* Ctrl-U clears ONE LINE, not the box (seen on 2.1.296): a two-line paste takes
|
|
360
|
+
* three presses — the last line, the newline, the first line. Progress cannot be
|
|
361
|
+
* read off `inputText`, which sees the first line only and therefore stays put
|
|
362
|
+
* while everything under it goes; `boxText` is what makes each press visible.
|
|
363
|
+
* A run of presses that leaves the SCREEN untouched is a box with nothing left
|
|
364
|
+
* to clear (or one that refuses to), and is given up on rather than hammered.
|
|
365
|
+
*/
|
|
366
|
+
async function emptyBox(pilot, clearMs) {
|
|
367
|
+
let stuck = 0;
|
|
368
|
+
for (let press = 0; press < MAX_CLEARS && stuck < 2; press++) {
|
|
369
|
+
const shown = boxText(pilot.screen());
|
|
370
|
+
if (shown === "")
|
|
371
|
+
return;
|
|
372
|
+
pilot.clearInput();
|
|
373
|
+
try {
|
|
374
|
+
await pilot.waitFor((s) => boxText(s) !== shown, { timeoutMs: Math.min(clearMs, CLEAR_STEP_MS) });
|
|
375
|
+
stuck = 0;
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
// Two presses that moved nothing: there is nothing left to clear. That is
|
|
379
|
+
// also the resting state of a FRESH session, whose box shows an example
|
|
380
|
+
// (`❯ Try "create a util logging.py that…"`) that Ctrl-U leaves exactly
|
|
381
|
+
// as it is — verified on 2.1.301, where it neither clears nor rotates. So
|
|
382
|
+
// the first prompt of a session pays two harmless presses, and every
|
|
383
|
+
// later one pays nothing: an empty box is returned on the first read.
|
|
384
|
+
stuck++;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Did what the box held before the paste survive it?
|
|
390
|
+
*
|
|
391
|
+
* Compares the FIRST line only, and a bounded slice of it: a long prompt makes
|
|
392
|
+
* the box wrap and scroll, so the rest of `before` may no longer be on screen
|
|
393
|
+
* even though nothing was replaced.
|
|
394
|
+
*
|
|
395
|
+
* The cost of this reading is one wasted attempt when you send the very same
|
|
396
|
+
* message twice in a row ("ok", "oui") — the suggestion ghost then carries your
|
|
397
|
+
* own words, so the paste looks like it joined them. The box is cleared, the
|
|
398
|
+
* retry pastes into an empty one, and the message goes out. That beats the
|
|
399
|
+
* alternative, which charges every single message a Ctrl-U and a 400 ms wait
|
|
400
|
+
* to find out what is in a box that is almost always only a ghost.
|
|
401
|
+
*/
|
|
402
|
+
function survives(before, now) {
|
|
403
|
+
const head = before.split("\n")[0].trim().slice(0, 40);
|
|
404
|
+
return head.length > 0 && now.includes(head);
|
|
405
|
+
}
|
|
293
406
|
export async function typeIntoBox(pilot, text, { attempts = 6, appearMs = 2_000, settleMs = 400, clearMs = 1_000, prelude } = {}) {
|
|
294
407
|
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
|
|
408
|
+
// "Landed" means the box DIFFERS from what it showed just before, not that
|
|
409
|
+
// it is non-empty: an empty box is not always blank. Before the first prompt
|
|
410
|
+
// of a session, Claude Code (seen on 2.1.285) fills it with an example —
|
|
411
|
+
// `❯ Try "refactor <filepath>"` — so "non-empty" was true before anything
|
|
412
|
+
// was pasted, and a paste the TUI dropped was followed by Enter on a box
|
|
413
|
+
// holding nothing. Comparing with the state read just before stays
|
|
414
|
+
// content-agnostic (a collapsed "[Pasted text +N lines]" differs from it as
|
|
415
|
+
// well as the text would) and needs no list of hint strings, which would rot
|
|
416
|
+
// with the next release. Re-read on every attempt, after a recovery has run.
|
|
417
|
+
const before = boxText(pilot.screen());
|
|
298
418
|
// N+1 pastes, and the LAST must be the message. Claude Code decides whether
|
|
299
419
|
// a paste stays inline when it is the CURRENT one and leaves every earlier
|
|
300
420
|
// one as it then became, so pasting separately is what puts the injected
|
|
@@ -309,66 +429,45 @@ export async function typeIntoBox(pilot, text, { attempts = 6, appearMs = 2_000,
|
|
|
309
429
|
for (const chunk of prelude ? (Array.isArray(prelude) ? prelude : [prelude]) : []) {
|
|
310
430
|
if (!chunk)
|
|
311
431
|
continue;
|
|
312
|
-
const seen = pilot.screen();
|
|
432
|
+
const seen = boxText(pilot.screen());
|
|
313
433
|
pilot.paste(chunk);
|
|
314
434
|
try {
|
|
315
|
-
|
|
316
|
-
// once a chunk has filled it every later one lands on a continuation
|
|
317
|
-
// line and the box's visible text stops moving.
|
|
318
|
-
await pilot.waitFor((s) => s !== seen, { timeoutMs: appearMs });
|
|
435
|
+
await pilot.waitFor((s) => boxText(s) !== seen, { timeoutMs: appearMs });
|
|
319
436
|
}
|
|
320
437
|
catch {
|
|
321
438
|
// A chunk never showed. Fall through and paste the rest anyway: losing
|
|
322
439
|
// the context is survivable, losing the message is not.
|
|
323
440
|
}
|
|
324
441
|
}
|
|
325
|
-
|
|
326
|
-
// line alone, so once a prelude has filled that line everything appended
|
|
327
|
-
// after it lands on continuation lines and `inputText` stops moving. Waiting
|
|
328
|
-
// on it then times out on a paste that arrived perfectly — which is exactly
|
|
329
|
-
// what the first version of this did, on every prelude long enough to wrap.
|
|
330
|
-
const afterPrelude = pilot.screen();
|
|
442
|
+
const afterPrelude = boxText(pilot.screen());
|
|
331
443
|
pilot.paste(text);
|
|
332
444
|
try {
|
|
445
|
+
// With no prelude the middle term is the same check as before, unchanged.
|
|
333
446
|
await pilot.waitFor((s) => {
|
|
334
|
-
const now =
|
|
335
|
-
|
|
336
|
-
return false; // nothing in the box yet
|
|
337
|
-
// With no prelude this is the original condition, unchanged.
|
|
338
|
-
return !prelude || s !== afterPrelude;
|
|
447
|
+
const now = boxText(s);
|
|
448
|
+
return now !== "" && now !== before && now !== afterPrelude;
|
|
339
449
|
}, { timeoutMs: appearMs });
|
|
340
|
-
return true;
|
|
341
450
|
}
|
|
342
451
|
catch {
|
|
343
452
|
await delay(settleMs); // let a paste that is still in flight land
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
return now === "" || now === before;
|
|
347
|
-
};
|
|
348
|
-
// `before` (not `beforeText`) on purpose: a retry re-pastes the prelude,
|
|
349
|
-
// so the box has to come back to what it was before EITHER paste.
|
|
350
|
-
// Ctrl-U clears ONE line, not the box (seen on 2.1.296): a two-line paste
|
|
351
|
-
// takes three presses — the last line, the newline, the first line. Two
|
|
352
|
-
// presses left the first line behind and the next attempt pasted after it,
|
|
353
|
-
// which is how a prompt arrived as its header twice and its text nowhere.
|
|
354
|
-
// So press until the box reads clear. Progress cannot be read off the box:
|
|
355
|
-
// `inputText` sees its FIRST line only, which stays put while the lines
|
|
356
|
-
// under it go. The whole screen is what moves, so a run of presses that
|
|
357
|
-
// leaves it untouched is a screen with nothing to clear — given up on, and
|
|
358
|
-
// left to the next attempt rather than pasted into blindly.
|
|
359
|
-
let stuck = 0;
|
|
360
|
-
for (let press = 0; press < MAX_CLEARS && stuck < 3; press++) {
|
|
361
|
-
const shown = pilot.screen();
|
|
362
|
-
pilot.clearInput();
|
|
363
|
-
try {
|
|
364
|
-
await pilot.waitFor(isClear, { timeoutMs: Math.min(clearMs, CLEAR_STEP_MS) });
|
|
365
|
-
break;
|
|
366
|
-
}
|
|
367
|
-
catch {
|
|
368
|
-
stuck = pilot.screen() === shown ? stuck + 1 : 0;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
453
|
+
await emptyBox(pilot, clearMs);
|
|
454
|
+
continue;
|
|
371
455
|
}
|
|
456
|
+
// It is in the box. On its own, or on top of what was already there?
|
|
457
|
+
//
|
|
458
|
+
// A box that reads non-empty is usually a GHOST: Claude Code offers the
|
|
459
|
+
// previous message as a greyed-out suggestion, and any paste wipes it out
|
|
460
|
+
// (verified on 2.1.301 — typing replaces it, while Ctrl-U, Ctrl-K and
|
|
461
|
+
// Escape all leave it exactly where it is, and backspacing to empty brings
|
|
462
|
+
// it back). After an interrupt, though, the box holds the real prompt the
|
|
463
|
+
// TUI put back, and pasting there submits two messages glued into one.
|
|
464
|
+
// A plain screen capture renders the two identically, so this does not
|
|
465
|
+
// guess: it pastes, then asks whether what was there is still there.
|
|
466
|
+
if (!survives(before, boxText(pilot.screen())))
|
|
467
|
+
return true;
|
|
468
|
+
// It joined the leftovers. Throw the attempt away — no settle delay, the
|
|
469
|
+
// paste has demonstrably landed — and start again on an empty box.
|
|
470
|
+
await emptyBox(pilot, clearMs);
|
|
372
471
|
}
|
|
373
472
|
return false;
|
|
374
473
|
}
|
package/dist/detect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -3049,6 +3049,41 @@ function dialogSettleKey(screen) {
|
|
|
3049
3049
|
const d = detectDialog(screen);
|
|
3050
3050
|
return d && !SUBMIT_PAGE.test(screen) ? dialogKey(d) : null;
|
|
3051
3051
|
}
|
|
3052
|
+
/**
|
|
3053
|
+
* Type a prompt into the TUI, holding any interrupt that arrives meanwhile.
|
|
3054
|
+
*
|
|
3055
|
+
* The window is small and it is exactly the one two fast Telegram messages fall
|
|
3056
|
+
* into: the first is still being pasted when the second is refused as `busy`,
|
|
3057
|
+
* and the bridge answers a refusal with an Escape. Pressed then, it deletes the
|
|
3058
|
+
* text being typed instead of stopping a turn — and an empty box is what
|
|
3059
|
+
* `submit` reads as "sent", so the first message disappears without a word.
|
|
3060
|
+
* Held until the prompt is really in, it does what it was asked to do.
|
|
3061
|
+
*/
|
|
3062
|
+
async function submitGuarded(s, text, prelude) {
|
|
3063
|
+
s.submitting = true;
|
|
3064
|
+
let sent = false;
|
|
3065
|
+
try {
|
|
3066
|
+
await s.pilot.submit(text, prelude);
|
|
3067
|
+
sent = true;
|
|
3068
|
+
}
|
|
3069
|
+
finally {
|
|
3070
|
+
s.submitting = false;
|
|
3071
|
+
const held = s.pendingInterrupt;
|
|
3072
|
+
s.pendingInterrupt = undefined;
|
|
3073
|
+
if (held) {
|
|
3074
|
+
// Only a submit that LANDED started a turn to interrupt. After one that
|
|
3075
|
+
// failed the key is still worth pressing — it clears the box someone is
|
|
3076
|
+
// waiting on — but claiming a turn was interrupted would hand the next
|
|
3077
|
+
// one `finishTurn`'s fast settle bar on no evidence at all.
|
|
3078
|
+
if (sent)
|
|
3079
|
+
s.interruptedAt = Date.now();
|
|
3080
|
+
try {
|
|
3081
|
+
s.pilot.press(held);
|
|
3082
|
+
}
|
|
3083
|
+
catch { /* pane gone */ }
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3052
3087
|
async function finishTurn(s) {
|
|
3053
3088
|
s.busy = true;
|
|
3054
3089
|
// Turn found already running (not started by us): typically after a server
|
|
@@ -3787,7 +3822,7 @@ wss.on("connection", (ws, req) => {
|
|
|
3787
3822
|
if (rows.length)
|
|
3788
3823
|
ledgerPrelude = formatLedgerChunks(rows, total);
|
|
3789
3824
|
}
|
|
3790
|
-
await session
|
|
3825
|
+
await submitGuarded(session, submitText, ledgerPrelude);
|
|
3791
3826
|
if (ledgerSeen !== null) {
|
|
3792
3827
|
session.ledgerSeenAt = ledgerSeen;
|
|
3793
3828
|
// The live channel list prunes the watermarks of agents that are
|
|
@@ -3824,7 +3859,7 @@ wss.on("connection", (ws, req) => {
|
|
|
3824
3859
|
// "did the text appear?" check holds in shell mode too.
|
|
3825
3860
|
session.pilot.write("!");
|
|
3826
3861
|
await session.pilot.waitFor(isShellMode, { timeoutMs: 5_000 });
|
|
3827
|
-
await session
|
|
3862
|
+
await submitGuarded(session, command);
|
|
3828
3863
|
}
|
|
3829
3864
|
catch (e) {
|
|
3830
3865
|
// Leave no stray `!` behind: a half-entered shell mode would turn the
|
|
@@ -3948,6 +3983,12 @@ wss.on("connection", (ws, req) => {
|
|
|
3948
3983
|
// the end state is known, so `finishTurn` may stop proving it the
|
|
3949
3984
|
// slow way. Only while busy — an escape at rest ends no turn.
|
|
3950
3985
|
if ((msg.key === "escape" || msg.key === "ctrl-c") && session.busy) {
|
|
3986
|
+
// ...but not while the prompt is still being typed: there the
|
|
3987
|
+
// key would delete the text rather than stop a turn. Hold it.
|
|
3988
|
+
if (session.submitting) {
|
|
3989
|
+
session.pendingInterrupt = msg.key;
|
|
3990
|
+
break;
|
|
3991
|
+
}
|
|
3951
3992
|
session.interruptedAt = Date.now();
|
|
3952
3993
|
}
|
|
3953
3994
|
session.pilot.press(msg.key);
|