omniharness-cli 0.1.86 → 0.1.87
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/ui/keys.js +15 -3
- package/dist/ui/terminalInterface.js +31 -11
- package/package.json +1 -1
package/dist/ui/keys.js
CHANGED
|
@@ -102,10 +102,22 @@ export function parseRawKey(chunk) {
|
|
|
102
102
|
return null;
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
|
-
* True when `value` is a CSI-u encoded key
|
|
106
|
-
* events, push/pop echoes, query answers),
|
|
105
|
+
* True when `value` is a CSI-u encoded key, a protocol response (kitty key
|
|
106
|
+
* events, push/pop echoes, query answers), or a DECRQM mode-report reply
|
|
107
|
+
* (`CSI ? Ps ; Pm $ y`, e.g. the answer to the synchronized-output query) —
|
|
108
|
+
* never plain text to insert.
|
|
109
|
+
*
|
|
110
|
+
* `value` here is Ink's own parsed form, which strips the leading ESC before
|
|
111
|
+
* handing the rest to `useInput`. A terminal's reply to a query this project
|
|
112
|
+
* sends (synchronized output, in particular) arrives on the same stdin the
|
|
113
|
+
* editor reads from, and if nothing recognises it in this stripped form it is
|
|
114
|
+
* treated as pasted text and typed into whatever the user was editing — the
|
|
115
|
+
* escape sequence itself, landing in the input box. Some terminals are slow
|
|
116
|
+
* to answer that specific query, so this has to keep matching however late
|
|
117
|
+
* the reply arrives, not just during a short probe window at startup.
|
|
107
118
|
*/
|
|
108
119
|
export function isEncodedKey(value) {
|
|
109
|
-
return /^\[\d+(?:;\d+)*u$|^\[[><?]\d+(?:;\d+)*u$/.test(value)
|
|
120
|
+
return /^\[\d+(?:;\d+)*u$|^\[[><?]\d+(?:;\d+)*u$/.test(value)
|
|
121
|
+
|| /^\[\?\d+;\d\$y$/.test(value);
|
|
110
122
|
}
|
|
111
123
|
//# sourceMappingURL=keys.js.map
|
|
@@ -334,22 +334,41 @@ export function TerminalInterface({ engine }) {
|
|
|
334
334
|
stdout.on('resize', onResize);
|
|
335
335
|
stdout.write(KITTY_PUSH);
|
|
336
336
|
let kittyTimer;
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
337
|
+
// Two independent probes, not one shared listener. They used to be a
|
|
338
|
+
// single handler torn down together after 300ms, on the assumption both
|
|
339
|
+
// replies would have arrived by then. Some terminals answer the
|
|
340
|
+
// synchronized-output query well after that — observed landing right
|
|
341
|
+
// around a resize, though the terminal's own reasons for the delay are
|
|
342
|
+
// opaque from here — and a listener already removed cannot catch a late
|
|
343
|
+
// reply. Two things followed from that: synchronized output silently
|
|
344
|
+
// never turned on for the rest of the session, and the reply itself, with
|
|
345
|
+
// nothing left to claim it, reached Ink's own useInput and got typed into
|
|
346
|
+
// the input box as literal text (the isEncodedKey guard now recognises
|
|
347
|
+
// and drops that shape regardless, but the actual fix is to keep
|
|
348
|
+
// listening for it rather than lean on that alone).
|
|
349
|
+
const onSyncProbe = (chunk) => {
|
|
350
|
+
if (syncRestoreRef.current !== null)
|
|
351
|
+
return;
|
|
352
|
+
if (!isSyncOutputReply(chunk.toString()))
|
|
353
|
+
return;
|
|
354
|
+
syncRestoreRef.current = wrapSynchronizedOutput(stdout);
|
|
355
|
+
stdin?.off('data', onSyncProbe);
|
|
356
|
+
};
|
|
357
|
+
// The kitty check is a UI decision — whether Ctrl+letter and a distinct
|
|
358
|
+
// Shift+Tab are available — that has to resolve one way or the other, so
|
|
359
|
+
// it keeps a bounded timeout; "no answer in 300ms" is itself the answer.
|
|
360
|
+
const onKittyProbe = (chunk) => {
|
|
361
|
+
if (!isKittyQueryResponse(chunk.toString()))
|
|
344
362
|
return;
|
|
345
363
|
if (kittyTimer)
|
|
346
364
|
clearTimeout(kittyTimer);
|
|
347
|
-
stdin?.off('data',
|
|
365
|
+
stdin?.off('data', onKittyProbe);
|
|
348
366
|
setKitty(true);
|
|
349
367
|
};
|
|
350
368
|
if (stdin) {
|
|
351
|
-
stdin.on('data',
|
|
352
|
-
|
|
369
|
+
stdin.on('data', onSyncProbe);
|
|
370
|
+
stdin.on('data', onKittyProbe);
|
|
371
|
+
kittyTimer = setTimeout(() => { setKitty(false); stdin.off('data', onKittyProbe); }, 300);
|
|
353
372
|
stdout.write(SYNC_QUERY);
|
|
354
373
|
stdout.write(KITTY_QUERY);
|
|
355
374
|
}
|
|
@@ -432,7 +451,8 @@ export function TerminalInterface({ engine }) {
|
|
|
432
451
|
return () => {
|
|
433
452
|
if (kittyTimer)
|
|
434
453
|
clearTimeout(kittyTimer);
|
|
435
|
-
stdin?.off('data',
|
|
454
|
+
stdin?.off('data', onSyncProbe);
|
|
455
|
+
stdin?.off('data', onKittyProbe);
|
|
436
456
|
stdout.off('resize', onResize); // resizeDebounce cancels the coalesced timer on .off itself
|
|
437
457
|
const pendingApproval = approvalResolve.current;
|
|
438
458
|
approvalResolve.current = null;
|