koneck 2.128.35 → 2.128.37

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/ink-chat.js CHANGED
@@ -4,7 +4,7 @@ import { Box, Static, Text, render, useApp, useInput, useStdin } from 'ink';
4
4
  import { execa } from 'execa';
5
5
  import chalk from 'chalk';
6
6
  import { resolveAgentConcurrency, toolsUnsupportedNotice } from './engine-facts.js';
7
- import { withSynchronizedFrames, probeSynchronizedOutput } from './frame-sync.js';
7
+ import { withSynchronizedFrames, withUsableSize, probeSynchronizedOutput } from './frame-sync.js';
8
8
  import { pacedInterval, startingInterval, floorFor, shouldDrawFrame } from './frame-pace.js';
9
9
  import { estimateCost, formatCost, rateText } from './pricing.js';
10
10
  import { generateSessionId, saveSession, listSessions, loadSession, relativeAge, renameSession, forkSession, archiveSession, findSession, } from './session.js';
@@ -2751,7 +2751,7 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
2751
2751
  * a keystroke.
2752
2752
  */
2753
2753
  if (prev !== cols)
2754
- redrawScreenRef.current?.();
2754
+ redrawScreenRef.current?.({ keepScrollback: true });
2755
2755
  return cols;
2756
2756
  });
2757
2757
  };
@@ -3209,7 +3209,17 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
3209
3209
  * lives in the session rather than in the terminal's memory of it.
3210
3210
  */
3211
3211
  redrawScreenRef.current = redrawScreen;
3212
- function redrawScreen() {
3212
+ /**
3213
+ * Repaint the terminal from scratch.
3214
+ *
3215
+ * `keepScrollback` is the difference between the two callers. Ctrl+L is somebody asking for a
3216
+ * clean slate after something has gone wrong on screen, and a stranded frame that has scrolled
3217
+ * out of view is still in the buffer waiting to come back — so that one takes the scrollback
3218
+ * with it. A resize is not a request for anything: it re-flows the conversation because the
3219
+ * width changed, and throwing away everything the person had scrolled past would be a far
3220
+ * larger thing than they asked for.
3221
+ */
3222
+ function redrawScreen(opts = {}) {
3213
3223
  if (!process.stdout.isTTY)
3214
3224
  return;
3215
3225
  // Ink's own clear first. It erases the frame using its own count of it and then resets that
@@ -3219,7 +3229,7 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
3219
3229
  // Then the screen, and the scrollback with it — a stranded frame that has scrolled out of view
3220
3230
  // is still in the buffer, and leaving it there means it comes back on the next scroll — and
3221
3231
  // home the cursor, which is where Ink will now draw.
3222
- process.stdout.write('\u001b[2J\u001b[3J\u001b[H');
3232
+ process.stdout.write(opts.keepScrollback ? '\u001b[2J\u001b[H' : '\u001b[2J\u001b[3J\u001b[H');
3223
3233
  // The transcript has just been erased along with everything else, so it has to be written
3224
3234
  // again — and writing it again is also what re-flows it to the current width.
3225
3235
  setStaticEpoch(n => n + 1);
@@ -7253,7 +7263,34 @@ export async function runInkChatMode(config) {
7253
7263
  * frame is a visible blink of the whole screen. 150ms at worst, once, on startup.
7254
7264
  */
7255
7265
  const synchronizedFrames = await probeSynchronizedOutput().catch(() => false);
7256
- const app = render(_jsx(App, { config: config, synchronizedFrames: synchronizedFrames, clearFrame: () => inkClear?.() }), { stdout: withSynchronizedFrames(process.stdout),
7266
+ /*
7267
+ * A clean screen to start on.
7268
+ *
7269
+ * KONECK opened wherever the shell had got to, so a session begun after an `npm install` sat
7270
+ * under a wall of its output with the banner halfway down the screen — it read as another
7271
+ * command that had printed something, rather than as a program that had taken over. Reported
7272
+ * exactly that way: "it fails to take over the terminal and not appear as if it's a command".
7273
+ *
7274
+ * `ESC[2J ESC[H` and nothing more. Deliberately not `ESC[3J`, which empties the scrollback too:
7275
+ * whatever was on screen a moment ago is still there to scroll back to, which is the difference
7276
+ * between clearing the screen and throwing away somebody's last command. Same sequence `clear`
7277
+ * uses, for the same reason.
7278
+ *
7279
+ * Written before Ink starts, so its idea of what it has drawn begins at zero and matches the
7280
+ * screen. Doing this after the first frame is what once left a dead copy of the interface
7281
+ * pinned below a working one.
7282
+ *
7283
+ * Not on the alternate screen, which arrives blank by definition, and not when the output is
7284
+ * not a terminal at all.
7285
+ */
7286
+ if (config.clearOnStart !== false && process.stdout.isTTY
7287
+ && initialAltScreen(config, synchronizedFrames) === false) {
7288
+ process.stdout.write('\u001b[2J\u001b[H');
7289
+ }
7290
+ const app = render(_jsx(App, { config: config, synchronizedFrames: synchronizedFrames, clearFrame: () => inkClear?.() }),
7291
+ // Sized first, then bracketed: Ink must never be handed a stream that
7292
+ // says it is zero rows tall. See withUsableSize.
7293
+ { stdout: withSynchronizedFrames(withUsableSize(process.stdout)),
7257
7294
  exitOnCtrlC: false, patchConsole: false });
7258
7295
  inkClear = app.clear;
7259
7296
  // The engine is imported on demand so the banner and the prompt are not waiting on the OpenAI