koneck 2.125.0 → 2.127.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.
@@ -47,8 +47,9 @@ const ON_TIME_FRACTION = 0.2;
47
47
  * Pure, so the pacing can be asserted rather than eyeballed: the same pair of numbers always gives
48
48
  * the same answer, and the curve can be checked at both ends without a terminal.
49
49
  */
50
- export function pacedInterval(current, deliveredMs) {
51
- const asked = Math.max(MIN_FRAME_MS, Math.min(MAX_FRAME_MS, current));
50
+ export function pacedInterval(current, deliveredMs, floor = MIN_FRAME_MS) {
51
+ const target = Math.max(MIN_FRAME_MS, Math.min(MAX_FRAME_MS, floor));
52
+ const asked = Math.max(target, Math.min(MAX_FRAME_MS, current));
52
53
  const late = deliveredMs - asked;
53
54
  // Later than the frame's own budget: the machine cannot paint this fast. Ask for less — at least
54
55
  // as long as the frame actually took, so the next request is one it has been shown to manage.
@@ -57,9 +58,35 @@ export function pacedInterval(current, deliveredMs) {
57
58
  }
58
59
  // Comfortably on time and currently backed off: ease toward the target, gently. A fifth at a
59
60
  // time takes several good frames to recover, which is the point — one fast frame proves little.
60
- if (late <= asked * ON_TIME_FRACTION && asked > MIN_FRAME_MS) {
61
- return Math.max(MIN_FRAME_MS, Math.round(asked * 0.8));
61
+ if (late <= asked * ON_TIME_FRACTION && asked > target) {
62
+ return Math.max(target, Math.round(asked * 0.8));
62
63
  }
63
64
  return asked;
64
65
  }
66
+ /**
67
+ * The rate to start from, given whether the terminal composites a redraw.
68
+ *
69
+ * In alt-screen mode a frame rewrites the whole screen. A terminal that implements synchronized
70
+ * output presents that as one picture, so it can be done often and looks smooth. A terminal that
71
+ * does not shows the erase, so every frame is a visible blink of the entire interface — and the
72
+ * honest response is to do it far less often, not to keep blinking twelve times a second because
73
+ * the animation would be prettier if the terminal were better.
74
+ *
75
+ * Four frames a second still reads as a spinner turning. It is a compromise, and it is the right
76
+ * way round: a slightly steppy spinner is a cosmetic loss, a blinking screen is why somebody stops
77
+ * using the tool.
78
+ */
79
+ export const UNSYNCED_FRAME_MS = 250;
80
+ export function startingInterval(synchronized) {
81
+ return synchronized ? MIN_FRAME_MS : UNSYNCED_FRAME_MS;
82
+ }
83
+ /**
84
+ * The floor for this terminal: the pacer must never speed back up past what it can show cleanly.
85
+ *
86
+ * Without this the recovery path would walk a blinking terminal back to 80ms the moment a few
87
+ * frames arrived on time — the machine was keeping up, which was never the problem.
88
+ */
89
+ export function floorFor(synchronized) {
90
+ return synchronized ? MIN_FRAME_MS : UNSYNCED_FRAME_MS;
91
+ }
65
92
  //# sourceMappingURL=frame-pace.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"frame-pace.js","sourceRoot":"","sources":["../src/frame-pace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAE/B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B,oFAAoF;AACpF,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,WAAmB;IAChE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,WAAW,GAAG,KAAK,CAAC;IAEjC,iGAAiG;IACjG,8FAA8F;IAC9F,IAAI,IAAI,GAAG,KAAK,GAAG,aAAa,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,6FAA6F;IAC7F,gGAAgG;IAChG,IAAI,IAAI,IAAI,KAAK,GAAG,gBAAgB,IAAI,KAAK,GAAG,YAAY,EAAE,CAAC;QAC7D,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"frame-pace.js","sourceRoot":"","sources":["../src/frame-pace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAE/B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B,oFAAoF;AACpF,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,WAAmB,EAAE,KAAK,GAAG,YAAY;IACtF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;IACrE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,WAAW,GAAG,KAAK,CAAC;IAEjC,iGAAiG;IACjG,8FAA8F;IAC9F,IAAI,IAAI,GAAG,KAAK,GAAG,aAAa,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,6FAA6F;IAC7F,gGAAgG;IAChG,IAAI,IAAI,IAAI,KAAK,GAAG,gBAAgB,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAGD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC,MAAM,UAAU,gBAAgB,CAAC,YAAqB;IACpD,OAAO,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC;AACzD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,YAAqB;IAC5C,OAAO,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC;AACzD,CAAC"}
@@ -40,4 +40,29 @@ export declare function synchronizedFrame(chunk: string): string;
40
40
  * on the stream the terminal actually resizes rather than on a copy that never hears about it.
41
41
  */
42
42
  export declare function withSynchronizedFrames<T extends NodeJS.WriteStream>(stream: T): T;
43
+ /**
44
+ * Whether this terminal really implements synchronized output, asked rather than assumed.
45
+ *
46
+ * Setting mode 2026 is safe everywhere — an unrecognised private mode is a defined no-op — so
47
+ * nothing had to be known in advance to start using it. But whether it *works* decides something
48
+ * else entirely: how often the whole screen may be redrawn.
49
+ *
50
+ * In alt-screen mode the transcript is re-rendered every frame, so each animation tick rewrites the
51
+ * entire screen. On a terminal that composites the update that is invisible and the animation can
52
+ * run fast. On one that does not, every tick is an erase the eye can see, twelve times a second —
53
+ * reported as "the whole cli blinks when it is working, it blinks a lot ... otherwise people won't
54
+ * use it". Those two terminals want opposite frame rates, and there is no number that suits both.
55
+ *
56
+ * So the terminal is asked. DECRQM (CSI ? 2026 $p) makes it report the mode: a reply of 1 or 2 means
57
+ * it knows the mode (set or reset), 0 means it does not recognise it, and no reply at all means the
58
+ * same thing in practice. Silence is treated as unsupported, which is both the safe default and
59
+ * self-correcting: a terminal that implements the mode answers in microseconds, so the only thing a
60
+ * timeout costs is a slower animation on a terminal that was going to flash anyway.
61
+ *
62
+ * Asked once, before Ink starts, because it reads a reply from stdin and Ink owns stdin afterwards.
63
+ */
64
+ export declare function probeSynchronizedOutput(stdout?: {
65
+ isTTY?: boolean;
66
+ write?: (s: string) => unknown;
67
+ }, stdin?: NodeJS.ReadStream, env?: Record<string, string | undefined>, timeoutMs?: number): Promise<boolean>;
43
68
  //# sourceMappingURL=frame-sync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"frame-sync.d.ts","sourceRoot":"","sources":["../src/frame-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAOH,4EAA4E;AAC5E,wBAAgB,uBAAuB,CACrC,MAAM,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAmB,EAC5C,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,OAAO,CAMT;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAmBjF"}
1
+ {"version":3,"file":"frame-sync.d.ts","sourceRoot":"","sources":["../src/frame-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAOH,4EAA4E;AAC5E,wBAAgB,uBAAuB,CACrC,MAAM,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAmB,EAC5C,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,OAAO,CAMT;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAmBjF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;CAAmB,EAC5E,KAAK,GAAE,MAAM,CAAC,UAA0B,EACxC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,SAAS,SAAM,GACd,OAAO,CAAC,OAAO,CAAC,CAmClB"}
@@ -77,4 +77,70 @@ export function withSynchronizedFrames(stream) {
77
77
  },
78
78
  });
79
79
  }
80
+ /**
81
+ * Whether this terminal really implements synchronized output, asked rather than assumed.
82
+ *
83
+ * Setting mode 2026 is safe everywhere — an unrecognised private mode is a defined no-op — so
84
+ * nothing had to be known in advance to start using it. But whether it *works* decides something
85
+ * else entirely: how often the whole screen may be redrawn.
86
+ *
87
+ * In alt-screen mode the transcript is re-rendered every frame, so each animation tick rewrites the
88
+ * entire screen. On a terminal that composites the update that is invisible and the animation can
89
+ * run fast. On one that does not, every tick is an erase the eye can see, twelve times a second —
90
+ * reported as "the whole cli blinks when it is working, it blinks a lot ... otherwise people won't
91
+ * use it". Those two terminals want opposite frame rates, and there is no number that suits both.
92
+ *
93
+ * So the terminal is asked. DECRQM (CSI ? 2026 $p) makes it report the mode: a reply of 1 or 2 means
94
+ * it knows the mode (set or reset), 0 means it does not recognise it, and no reply at all means the
95
+ * same thing in practice. Silence is treated as unsupported, which is both the safe default and
96
+ * self-correcting: a terminal that implements the mode answers in microseconds, so the only thing a
97
+ * timeout costs is a slower animation on a terminal that was going to flash anyway.
98
+ *
99
+ * Asked once, before Ink starts, because it reads a reply from stdin and Ink owns stdin afterwards.
100
+ */
101
+ export async function probeSynchronizedOutput(stdout = process.stdout, stdin = process.stdin, env = process.env, timeoutMs = 150) {
102
+ if (!wantsSynchronizedFrames(stdout, env))
103
+ return false;
104
+ if (!stdin.isTTY || typeof stdin.setRawMode !== 'function')
105
+ return false;
106
+ return new Promise(resolve => {
107
+ let settled = false;
108
+ let seen = '';
109
+ const wasRaw = stdin.isRaw === true;
110
+ const finish = (answer) => {
111
+ if (settled)
112
+ return;
113
+ settled = true;
114
+ clearTimeout(timer);
115
+ stdin.removeListener('data', onData);
116
+ try {
117
+ if (!wasRaw)
118
+ stdin.setRawMode(false);
119
+ }
120
+ catch { /* nothing to restore */ }
121
+ if (!wasRaw)
122
+ stdin.pause();
123
+ resolve(answer);
124
+ };
125
+ const onData = (chunk) => {
126
+ seen += chunk.toString('latin1');
127
+ // CSI ? 2026 ; <value> $y — 1 (set) or 2 (reset) mean the mode is known; 0 means it is not.
128
+ const m = /\x1b\[\?2026;([0-4])\$y/.exec(seen);
129
+ if (m)
130
+ finish(m[1] === '1' || m[1] === '2');
131
+ // Some terminals answer a mode they do not know with a bare "0" report; keep waiting for a
132
+ // recognisable reply otherwise, and let the timeout be the answer.
133
+ };
134
+ const timer = setTimeout(() => finish(false), timeoutMs);
135
+ try {
136
+ stdin.setRawMode(true);
137
+ stdin.resume();
138
+ stdin.on('data', onData);
139
+ stdout.write?.('\x1b[?2026$p');
140
+ }
141
+ catch {
142
+ finish(false);
143
+ }
144
+ });
145
+ }
80
146
  //# sourceMappingURL=frame-sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"frame-sync.js","sourceRoot":"","sources":["../src/frame-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,sFAAsF;AACtF,MAAM,KAAK,GAAG,aAAa,CAAC;AAC5B,2DAA2D;AAC3D,MAAM,GAAG,GAAG,aAAa,CAAC;AAE1B,4EAA4E;AAC5E,MAAM,UAAU,uBAAuB,CACrC,SAA8B,OAAO,CAAC,MAAM,EAC5C,MAA0C,OAAO,CAAC,GAAG;IAErD,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,GAAG,CAAC,qBAAqB,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACpD,qFAAqF;IACrF,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACnD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,0FAA0F;IAC1F,kBAAkB;IAClB,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAA+B,MAAS;IAC5E,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACpD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACvB,GAAG,CAAC,MAAM,EAAE,IAAI;YACd,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,8FAA8F;gBAC9F,yFAAyF;gBACzF,yFAAyF;gBACzF,OAAO,CAAC,KAAc,EAAE,GAAG,IAAe,EAAW,EAAE;oBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,KAA0D,CAAC;oBAChF,OAAO,OAAO,KAAK,KAAK,QAAQ;wBAC9B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC;wBACvD,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;gBACzC,CAAC,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAChD,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAClE,CAAC;KACF,CAAM,CAAC;AACV,CAAC"}
1
+ {"version":3,"file":"frame-sync.js","sourceRoot":"","sources":["../src/frame-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,sFAAsF;AACtF,MAAM,KAAK,GAAG,aAAa,CAAC;AAC5B,2DAA2D;AAC3D,MAAM,GAAG,GAAG,aAAa,CAAC;AAE1B,4EAA4E;AAC5E,MAAM,UAAU,uBAAuB,CACrC,SAA8B,OAAO,CAAC,MAAM,EAC5C,MAA0C,OAAO,CAAC,GAAG;IAErD,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,GAAG,CAAC,qBAAqB,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACpD,qFAAqF;IACrF,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACnD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,0FAA0F;IAC1F,kBAAkB;IAClB,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAA+B,MAAS;IAC5E,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACpD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACvB,GAAG,CAAC,MAAM,EAAE,IAAI;YACd,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,8FAA8F;gBAC9F,yFAAyF;gBACzF,yFAAyF;gBACzF,OAAO,CAAC,KAAc,EAAE,GAAG,IAAe,EAAW,EAAE;oBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,KAA0D,CAAC;oBAChF,OAAO,OAAO,KAAK,KAAK,QAAQ;wBAC9B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC;wBACvD,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;gBACzC,CAAC,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAChD,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAClE,CAAC;KACF,CAAM,CAAC;AACV,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,SAA8D,OAAO,CAAC,MAAM,EAC5E,QAA2B,OAAO,CAAC,KAAK,EACxC,MAA0C,OAAO,CAAC,GAAG,EACrD,SAAS,GAAG,GAAG;IAEf,IAAI,CAAC,uBAAuB,CAAC,MAA6B,EAAE,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAEzE,OAAO,IAAI,OAAO,CAAU,OAAO,CAAC,EAAE;QACpC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;QACpC,MAAM,MAAM,GAAG,CAAC,MAAe,EAAQ,EAAE;YACvC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACrC,IAAI,CAAC;gBAAC,IAAI,CAAC,MAAM;oBAAE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,wBAAwB,CAAC,CAAC;YAChF,IAAI,CAAC,MAAM;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,KAAa,EAAQ,EAAE;YACrC,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACjC,4FAA4F;YAC5F,MAAM,CAAC,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,CAAC;gBAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAC5C,2FAA2F;YAC3F,mEAAmE;QACrE,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;QACzD,IAAI,CAAC;YACH,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,EAAE,CAAC;YACf,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -316,7 +316,27 @@ export declare function defaultAltScreen(stdout?: {
316
316
  isTTY?: boolean;
317
317
  rows?: number;
318
318
  columns?: number;
319
- }, env?: NodeJS.ProcessEnv): boolean;
319
+ }, env?: NodeJS.ProcessEnv,
320
+ /**
321
+ * Whether this terminal composites a redraw, from the probe in frame-sync.ts.
322
+ *
323
+ * The deciding fact, and the reason this argument exists. On the alternate screen the frame is
324
+ * redrawn in place, which a terminal that implements synchronized output presents as one picture
325
+ * and one that does not shows as an erase — so the same interface is smooth on Windows Terminal
326
+ * and blinks on most Linux VTE terminals. Two further things follow from redrawing in place, and
327
+ * both were reported: a selection is destroyed by the next repaint, so text cannot be copied out
328
+ * — "only koneck cli i can't select/highlight and copy" — and there is no scrollback to select
329
+ * from in the first place.
330
+ *
331
+ * The terminal's own scrollback has none of those problems. Finished rows go through <Static>,
332
+ * which writes each one once and never touches it again: nothing to blink, and the text sits in
333
+ * the terminal's buffer to be selected like any other output. What it costs is the fixed frame —
334
+ * the side-by-side diff panel needs one, so opening that still switches over.
335
+ *
336
+ * So the alternate screen is used where it is invisible and avoided where it is not, rather than
337
+ * a default chosen for one machine and endured on the other.
338
+ */
339
+ compositesRedraws?: boolean): boolean;
320
340
  /**
321
341
  * The live diff panel — the work as it happens, beside the conversation.
322
342
  *
@@ -339,9 +359,11 @@ export declare function DiffPanel({ files, width, height }: {
339
359
  * Typechecking passes on that code and no test could reach it, because nothing in the suite mounted
340
360
  * an Ink app. Something does now.
341
361
  */
342
- export declare function App({ config: initialConfig, clearFrame }: {
362
+ export declare function App({ config: initialConfig, clearFrame, synchronizedFrames }: {
343
363
  config: AgentConfig;
344
364
  clearFrame?: () => void;
365
+ /** Whether this terminal composites a redraw; see frame-sync.ts. */
366
+ synchronizedFrames?: boolean;
345
367
  }): React.JSX.Element;
346
368
  export declare function runInkChatMode(config: AgentConfig): Promise<void>;
347
369
  //# sourceMappingURL=ink-chat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ink-chat.d.ts","sourceRoot":"","sources":["../src/ink-chat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ink-chat.d.ts","sourceRoot":"","sources":["../src/ink-chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AA0B3D,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAuCtE,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAiB5D,OAAO,EAA6C,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3F,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AAoD7D,KAAK,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AAGhD,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI9D;AAyED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAM7C;AA0BD,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BpE;AAED,qFAAqF;AACrF;;;;;GAKG;AASH,eAAO,MAAM,YAAY,mBAAuB,CAAC;AAEjD,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAchG;AAED,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAiB,GAAG,MAAM,CAM9E;AA6CD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGnE;AAoBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,YAAY,QAAS,CAAC;AAEnC;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAGtG;AAyBD,OAAO,EACL,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EACzC,KAAK,QAAQ,EAAE,KAAK,UAAU,GAC/B,MAAM,iBAAiB,CAAC;AA+EzB,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASpD;AAYD,8CAA8C;AAC9C,KAAK,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAClF,UAAU,UAAU;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;AAEtG,qGAAqG;AACrG,wBAAgB,mBAAmB,CACjC,QAAQ,GAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAa,GAC5D,UAAU,EAAE,CAId;AAUD,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAK7E;AAwBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAYR;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAElF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAWlF;AAyBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,WAAiC,GAAG,MAAM,GAAG,SAAS,CAgBhH;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAM/F;AAED,mGAAmG;AACnG,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,MAAM,EAAE,CAInG;AAGD,iGAAiG;AACjG,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAiBpE;AAQD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAMjF;AAGD;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;AAE7D,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACtD,GAAG,WAAW,CAMd;AAGD,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAKvF;AAGD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKtF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,GACZ,MAAM,CAMR;AAiCD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,UAAQ,GAAG,MAAM,CAEvD;AAED,KAAK,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC;AAElG,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,eAAe,EAAE,GAAG,MAAM,CAa1G;AAED,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,UAAQ,GAAG,MAAM,CAOzE;AAED,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,iGAAiG;AACjG,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9D;AAID,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAa7C,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQxE;AAED,kGAAkG;AAClG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,6EAA6E;AAC7E,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO9E;AAED,8FAA8F;AAC9F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,SAAI,GAAG,MAAM,CAGjF;AAED,oFAAoF;AACpF,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAsBpE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CASrF;AAED,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrF,GAAG,OAAO,CAEV;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,OAAO,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,sBAAsB,UAAQ,GAC7B,OAAO,GAAG,MAAM,GAAG,KAAK,CAc1B;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,sGAAsG;AACtG,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,EAC3B,eAAe,CAAC,EAAE,MAAM,EACxB,QAAQ,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAClC,MAAM,CAcR;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,OAAO,CAMnE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEzD;AA0ED;;;;;GAKG;AACH;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAU3D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAmB,EAC7E,GAAG,GAAE,MAAM,CAAC,UAAwB;AACpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,iBAAiB,UAAQ,GACxB,OAAO,CAQT;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtF,KAAK,CAAC,GAAG,CAAC,OAAO,CAiGnB;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,kBAA0B,EAAE,EACxE;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7C,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA0+JhE;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCvE"}
package/dist/ink-chat.js CHANGED
@@ -3,8 +3,8 @@ import React, { useState, useEffect, useRef } from 'react';
3
3
  import { Box, Static, Text, render, useApp, useInput, useStdin } from 'ink';
4
4
  import { execa } from 'execa';
5
5
  import { resolveAgentConcurrency, toolsUnsupportedNotice } from './engine-facts.js';
6
- import { withSynchronizedFrames } from './frame-sync.js';
7
- import { pacedInterval } from './frame-pace.js';
6
+ import { withSynchronizedFrames, probeSynchronizedOutput } from './frame-sync.js';
7
+ import { pacedInterval, startingInterval, floorFor } from './frame-pace.js';
8
8
  import { estimateCost, formatCost, rateText } from './pricing.js';
9
9
  import { generateSessionId, saveSession, listSessions, loadSession, relativeAge, renameSession, forkSession, archiveSession, findSession, } from './session.js';
10
10
  import { loadMemory } from './memory.js';
@@ -1159,7 +1159,27 @@ export function looksLikeMouseReport(input) {
1159
1159
  return true;
1160
1160
  return false;
1161
1161
  }
1162
- export function defaultAltScreen(stdout = process.stdout, env = process.env) {
1162
+ export function defaultAltScreen(stdout = process.stdout, env = process.env,
1163
+ /**
1164
+ * Whether this terminal composites a redraw, from the probe in frame-sync.ts.
1165
+ *
1166
+ * The deciding fact, and the reason this argument exists. On the alternate screen the frame is
1167
+ * redrawn in place, which a terminal that implements synchronized output presents as one picture
1168
+ * and one that does not shows as an erase — so the same interface is smooth on Windows Terminal
1169
+ * and blinks on most Linux VTE terminals. Two further things follow from redrawing in place, and
1170
+ * both were reported: a selection is destroyed by the next repaint, so text cannot be copied out
1171
+ * — "only koneck cli i can't select/highlight and copy" — and there is no scrollback to select
1172
+ * from in the first place.
1173
+ *
1174
+ * The terminal's own scrollback has none of those problems. Finished rows go through <Static>,
1175
+ * which writes each one once and never touches it again: nothing to blink, and the text sits in
1176
+ * the terminal's buffer to be selected like any other output. What it costs is the fixed frame —
1177
+ * the side-by-side diff panel needs one, so opening that still switches over.
1178
+ *
1179
+ * So the alternate screen is used where it is invisible and avoided where it is not, rather than
1180
+ * a default chosen for one machine and endured on the other.
1181
+ */
1182
+ compositesRedraws = false) {
1163
1183
  if (!stdout.isTTY)
1164
1184
  return false;
1165
1185
  if (env['CI'])
@@ -1170,7 +1190,7 @@ export function defaultAltScreen(stdout = process.stdout, env = process.env) {
1170
1190
  return false;
1171
1191
  if ((stdout.columns ?? 80) < 40)
1172
1192
  return false;
1173
- return true;
1193
+ return compositesRedraws;
1174
1194
  }
1175
1195
  /**
1176
1196
  * One diff line, syntax-coloured, on its tinted band.
@@ -1214,6 +1234,18 @@ export function DiffPanel({ files, width, height }) {
1214
1234
  for (const d of [...files].reverse()) {
1215
1235
  if (used + 2 > height)
1216
1236
  break;
1237
+ /*
1238
+ * A rule between files, so the panel reads as sections rather than one column of lines.
1239
+ *
1240
+ * Asked for, against Claude Code's panel as the reference: "it is clean and well structured".
1241
+ * The difference was structural, not chromatic — the colours were already right, but with a
1242
+ * blank line as the only separation two files' diffs ran together and the filename headers had
1243
+ * nothing to sit under. Drawn only between files, never above the first.
1244
+ */
1245
+ if (shownFiles > 0 && used + 1 < height) {
1246
+ body.push(_jsx(Text, { color: DIM, children: '─'.repeat(inner) }, `r-${d.path}`));
1247
+ used += 1;
1248
+ }
1217
1249
  const numbers = d.hunks.flatMap(h => h.lines.map(l => l.after ?? l.before ?? 0));
1218
1250
  const gutter = Math.max(3, String(Math.max(0, ...numbers)).length);
1219
1251
  const codeWidth = Math.max(12, inner - gutter - 2);
@@ -1266,7 +1298,7 @@ export function DiffPanel({ files, width, height }) {
1266
1298
  * Typechecking passes on that code and no test could reach it, because nothing in the suite mounted
1267
1299
  * an Ink app. Something does now.
1268
1300
  */
1269
- export function App({ config: initialConfig, clearFrame }) {
1301
+ export function App({ config: initialConfig, clearFrame, synchronizedFrames = false }) {
1270
1302
  const { exit } = useApp();
1271
1303
  const [cfg, setCfg] = useState(initialConfig);
1272
1304
  // Tool approval callbacks belong to a session created on an earlier render. Keep the control
@@ -1750,7 +1782,7 @@ export function App({ config: initialConfig, clearFrame }) {
1750
1782
  *
1751
1783
  * /altscreen off, or `altScreen: false` in config, goes back to the terminal's own scrollback.
1752
1784
  */
1753
- const [altScreen, setAltScreen] = useState(cfg.altScreen ?? defaultAltScreen());
1785
+ const [altScreen, setAltScreen] = useState(cfg.altScreen ?? defaultAltScreen(process.stdout, process.env, synchronizedFrames));
1754
1786
  /**
1755
1787
  * How many rows back from the newest the viewport is looking, in alt-screen mode.
1756
1788
  *
@@ -2198,6 +2230,17 @@ export function App({ config: initialConfig, clearFrame }) {
2198
2230
  /** Tools this turn has run, which is what separates work from a plain answer. */
2199
2231
  const turnToolsRef = useRef(0); // a tool failed and was worked around
2200
2232
  const busyStart = useRef(0);
2233
+ /*
2234
+ * Whether this terminal composites a redraw, decided once before Ink started.
2235
+ *
2236
+ * A ref rather than state: it never changes for the life of the process, and the ticker reads it
2237
+ * when it starts. It gates the frame rate, because in alt-screen mode every frame rewrites the
2238
+ * whole screen — invisible where the terminal composites it, a blink of the entire interface
2239
+ * where it does not. See frame-sync.ts and frame-pace.ts.
2240
+ */
2241
+ const syncedFramesRef = useRef(synchronizedFrames);
2242
+ /** Whether the diff panel is showing, so the transcript does not draw the same diff again. */
2243
+ const diffPanelOpenRef = useRef(false);
2201
2244
  const wordTimer = useRef(0);
2202
2245
  // Register on the session bus so other running KONECK instances can reach this one.
2203
2246
  useEffect(() => {
@@ -2276,11 +2319,12 @@ export function App({ config: initialConfig, clearFrame }) {
2276
2319
  * budget, and asking again just as soon only queues a frame that cannot be painted — which is
2277
2320
  * how a Pi ends up lagging while the same build feels instant on a laptop. See frame-pace.ts.
2278
2321
  */
2279
- let interval = FRAME_MS;
2322
+ const floor = floorFor(syncedFramesRef.current);
2323
+ let interval = startingInterval(syncedFramesRef.current);
2280
2324
  let asked = Date.now();
2281
2325
  const tick = () => {
2282
2326
  const now = Date.now();
2283
- interval = pacedInterval(interval, now - asked);
2327
+ interval = pacedInterval(interval, now - asked, floor);
2284
2328
  // Elapsed is read from the clock rather than counted in ticks, so a frame the event loop
2285
2329
  // delivers late moves the animation on by what actually passed instead of falling behind.
2286
2330
  const elapsed = now - busyStart.current;
@@ -3721,19 +3765,32 @@ export function App({ config: initialConfig, clearFrame }) {
3721
3765
  const want = arg.trim() === 'off' ? false : arg.trim() === 'on' ? true : !showDiffPanel;
3722
3766
  setShowDiffPanel(want);
3723
3767
  diffPanelTouchedRef.current = true;
3768
+ /*
3769
+ * Opening the panel switches to the alternate screen, because it needs a frame.
3770
+ *
3771
+ * The default is now the terminal's own scrollback wherever a repaint would be visible, so
3772
+ * asking for the panel used to be answered with "/altscreen on, then /diff" — two commands
3773
+ * to reach one feature, for a reason that is KONECK's business rather than the person's.
3774
+ * The panel is a fixed side-by-side layout and there is nowhere to put a second column in
3775
+ * scrollback, so asking for it is asking for the frame. Closing it hands the scrollback
3776
+ * back, and with it selectable text.
3777
+ */
3778
+ if (want && !altScreen)
3779
+ setAltScreen(true);
3780
+ if (!want && !(cfg.altScreen ?? false)
3781
+ && !defaultAltScreen(process.stdout, process.env, syncedFramesRef.current)) {
3782
+ setAltScreen(false);
3783
+ }
3724
3784
  const saved = { ...(await loadKoneckConfig()), diffPanel: want };
3725
3785
  await saveKoneckConfig(saved);
3726
3786
  setStored(saved);
3727
- addSystem(want && !altScreen
3728
- ? 'The diff panel needs the alternate screen, which this session is not using. '
3729
- + '/altscreen on, then /diff.'
3730
- : want && liveDiffs.length === 0
3731
- ? 'Diff panel on — it will appear beside the conversation with the first edit. '
3732
- + 'Saved as your default.'
3733
- : want
3734
- ? 'Diff panel open beside the conversation, following every edit as it lands. '
3735
- + '/diff to hide it.'
3736
- : 'Diff panel hidden. /diff to bring it back.');
3787
+ addSystem(want && liveDiffs.length === 0
3788
+ ? 'Diff panel on — it will appear beside the conversation with the first edit. '
3789
+ + 'Saved as your default.'
3790
+ : want
3791
+ ? 'Diff panel open beside the conversation, following every edit as it lands. '
3792
+ + '/diff to hide it.'
3793
+ : 'Diff panel hidden. /diff to bring it back.');
3737
3794
  return;
3738
3795
  }
3739
3796
  case '/altscreen':
@@ -5366,6 +5423,9 @@ export function App({ config: initialConfig, clearFrame }) {
5366
5423
  * scrollback full-width, and there is no frame to put a second column in.
5367
5424
  */
5368
5425
  const diffPanelOpen = showDiffPanel && altScreen && liveDiffs.length > 0;
5426
+ // Read by renderStep, which is defined above this line, so it goes through a ref rather than
5427
+ // depending on declaration order.
5428
+ diffPanelOpenRef.current = diffPanelOpen;
5369
5429
  const diffPanelWidth = diffPanelOpen
5370
5430
  ? Math.max(34, Math.min(Math.floor(uiWidth * 0.46), 96))
5371
5431
  : 0;
@@ -5420,7 +5480,7 @@ export function App({ config: initialConfig, clearFrame }) {
5420
5480
  const ms = (step.endedAt ?? Date.now()) - step.startedAt;
5421
5481
  const glyph = running ? SPINNER[spinFrame] : step.ok === false ? G.fail : G.ok;
5422
5482
  const color = running ? AMBER : step.ok === false ? CRIMSON : GREEN;
5423
- return (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: color, children: glyph }), _jsx(Text, { color: AMBER, bold: true, children: step.name }), _jsx(Text, { color: DIM, children: "\u00B7" }), _jsx(Text, { color: MUTED, children: fmtElapsed(ms) })] }), step.detail !== '' && (step.diffs ?? []).length === 0 && (_jsxs(Box, { paddingLeft: 2, gap: 1, children: [_jsx(Text, { color: DIM, children: "\u2514" }), _jsx(Text, { color: MUTED, children: step.detail })] })), step.ok === false && step.error && (_jsxs(Box, { paddingLeft: 2, gap: 1, children: [_jsx(Text, { color: DIM, children: "\u2514" }), _jsx(Text, { color: CRIMSON, children: fitCells(step.error, Math.max(20, barWidth - 6)) })] })), running && step.output && (_jsx(Box, { paddingLeft: 4, children: _jsx(Text, { color: DIM, children: fitCells(step.output, Math.max(20, barWidth - 6)) }) })), (step.diffs ?? []).map((d, i) => renderDiff(d, i))] }, key));
5483
+ return (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: color, children: glyph }), _jsx(Text, { color: AMBER, bold: true, children: step.name }), _jsx(Text, { color: DIM, children: "\u00B7" }), _jsx(Text, { color: MUTED, children: fmtElapsed(ms) })] }), step.detail !== '' && (step.diffs ?? []).length === 0 && (_jsxs(Box, { paddingLeft: 2, gap: 1, children: [_jsx(Text, { color: DIM, children: "\u2514" }), _jsx(Text, { color: MUTED, children: step.detail })] })), step.ok === false && step.error && (_jsxs(Box, { paddingLeft: 2, gap: 1, children: [_jsx(Text, { color: DIM, children: "\u2514" }), _jsx(Text, { color: CRIMSON, children: fitCells(step.error, Math.max(20, barWidth - 6)) })] })), running && step.output && (_jsx(Box, { paddingLeft: 4, children: _jsx(Text, { color: DIM, children: fitCells(step.output, Math.max(20, barWidth - 6)) }) })), !diffPanelOpenRef.current && (step.diffs ?? []).map((d, i) => renderDiff(d, i))] }, key));
5424
5484
  };
5425
5485
  /**
5426
5486
  * One transcript row.
@@ -5858,7 +5918,14 @@ export async function runInkChatMode(config) {
5858
5918
  // Frames go out bracketed as synchronized updates, so the erase-then-redraw Ink performs on
5859
5919
  // every repaint is composited by the terminal instead of being shown as a blank flash. That is
5860
5920
  // what allows the animation to run at FRAME_MS; see frame-sync.ts.
5861
- const app = render(_jsx(App, { config: config, clearFrame: () => inkClear?.() }), { stdout: withSynchronizedFrames(process.stdout),
5921
+ /*
5922
+ * Asked before Ink starts, because the reply arrives on stdin and Ink owns stdin from here.
5923
+ *
5924
+ * The answer sets the animation's floor: fast where a redraw is composited, slow where every
5925
+ * frame is a visible blink of the whole screen. 150ms at worst, once, on startup.
5926
+ */
5927
+ const synchronizedFrames = await probeSynchronizedOutput().catch(() => false);
5928
+ const app = render(_jsx(App, { config: config, synchronizedFrames: synchronizedFrames, clearFrame: () => inkClear?.() }), { stdout: withSynchronizedFrames(process.stdout),
5862
5929
  exitOnCtrlC: false, patchConsole: false });
5863
5930
  inkClear = app.clear;
5864
5931
  // The engine is imported on demand so the banner and the prompt are not waiting on the OpenAI