koneck 2.128.29 → 2.128.31

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.
@@ -454,12 +454,20 @@ export declare function initialAltScreen(cfg: {
454
454
  * fill the height available and the rest are counted, since a panel that scrolls past what you
455
455
  * wanted is no better than no panel.
456
456
  */
457
- export declare function DiffPanel({ files, width, height, activity, activityRows }: {
457
+ export declare function DiffPanel({ files, width, height, activity, activityRows, scroll }: {
458
458
  files: readonly FileDiff[];
459
459
  width: number;
460
460
  height: number;
461
461
  activity?: React.ReactNode;
462
462
  activityRows?: number;
463
+ /**
464
+ * How far back from the newest row the panel is looking.
465
+ *
466
+ * The panel scrolls independently of the conversation, which is the point of it being a
467
+ * panel: reading a diff should not mean losing your place in the transcript, and following
468
+ * the transcript should not drag the diff away from the hunk being read.
469
+ */
470
+ scroll?: number;
463
471
  }): React.JSX.Element;
464
472
  /**
465
473
  * Exported for one reason: so a test can mount it.
@@ -469,6 +477,34 @@ export declare function DiffPanel({ files, width, height, activity, activityRows
469
477
  * Typechecking passes on that code and no test could reach it, because nothing in the suite mounted
470
478
  * an Ink app. Something does now.
471
479
  */
480
+ /**
481
+ * Where each visual row of the composer begins and ends, as offsets into the draft.
482
+ *
483
+ * Not `wrapToWidth`, which normalises runs of whitespace and so cannot be mapped back to the
484
+ * text it was given. Moving a caret between rows needs the opposite property: every character
485
+ * accounted for, in its original position, so that row-and-column can be converted to an index
486
+ * and back without drifting.
487
+ *
488
+ * Greedy word wrap, breaking at the last space that fits and hard-splitting a word too long for
489
+ * a row — the same rule the composer is drawn with, so the rows here are the rows on screen.
490
+ */
491
+ export declare function composerRows(text: string, width: number): {
492
+ start: number;
493
+ end: number;
494
+ }[];
495
+ /**
496
+ * The caret one visual row up or down, or null when there is no such row.
497
+ *
498
+ * Null is the useful half: with nothing above, Up is free to mean "the previous prompt", which
499
+ * is what it has always meant and what a shell does. So a one-line draft keeps its history
500
+ * recall and a wrapped or multi-line one becomes editable in the middle, which is what was asked
501
+ * for — "must be able to move in lines/rows for easy editing/correcting when need to write in
502
+ * between".
503
+ *
504
+ * The column is kept where it can be and clamped to the end of a shorter row, as every editor
505
+ * does.
506
+ */
507
+ export declare function caretRowMove(text: string, caret: number, width: number, direction: -1 | 1): number | null;
472
508
  /**
473
509
  * The selected span of the composer, or null when nothing is selected.
474
510
  *
@@ -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":"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"}
package/dist/ink-chat.js CHANGED
@@ -502,6 +502,22 @@ export const WORD_HOLD_MS = 60_000;
502
502
  * appears frozen for seven seconds is worse than either.
503
503
  */
504
504
  export const HEARTBEAT_MS = 1_000;
505
+ /**
506
+ * The cursor, drawn as a painted cell rather than as a character.
507
+ *
508
+ * It was a literal U+2588 FULL BLOCK. Every other glyph in the interface goes through the glyph
509
+ * set, which drops to ASCII on Windows precisely because the console there cannot be relied on
510
+ * for them — and this one bypassed it, so on Windows the cursor was a character the font had no
511
+ * picture for and simply did not appear. Reported as exactly that: visible on Linux, absent on
512
+ * Windows.
513
+ *
514
+ * A space with a background colour needs no glyph from any font, and it is already how the
515
+ * cursor is drawn when it sits on a character mid-string. Now both cases are the same thing: a
516
+ * painted cell, in the same place, whatever the terminal has to draw with.
517
+ */
518
+ function Cursor() {
519
+ return _jsx(Text, { backgroundColor: CYAN, children: " " });
520
+ }
505
521
  /**
506
522
  * Whether the terminal should report the wheel to KONECK, when nothing has been saved either way.
507
523
  *
@@ -1427,7 +1443,7 @@ function renderCodeLine(text, kind, width, lang) {
1427
1443
  * fill the height available and the rest are counted, since a panel that scrolls past what you
1428
1444
  * wanted is no better than no panel.
1429
1445
  */
1430
- export function DiffPanel({ files, width, height, activity, activityRows = 0 }) {
1446
+ export function DiffPanel({ files, width, height, activity, activityRows = 0, scroll = 0 }) {
1431
1447
  const added = files.reduce((n, d) => n + d.added, 0);
1432
1448
  const removed = files.reduce((n, d) => n + d.removed, 0);
1433
1449
  // The persistent panel needs a visible boundary even before an edit arrives. Without one, its
@@ -1440,8 +1456,6 @@ export function DiffPanel({ files, width, height, activity, activityRows = 0 })
1440
1456
  let used = 0;
1441
1457
  let shownFiles = 0;
1442
1458
  for (const d of [...files].reverse()) {
1443
- if (used + 2 > bodyHeight)
1444
- break;
1445
1459
  /*
1446
1460
  * A rule between files, so the panel reads as sections rather than one column of lines.
1447
1461
  *
@@ -1450,7 +1464,7 @@ export function DiffPanel({ files, width, height, activity, activityRows = 0 })
1450
1464
  * blank line as the only separation two files' diffs ran together and the filename headers had
1451
1465
  * nothing to sit under. Drawn only between files, never above the first.
1452
1466
  */
1453
- if (shownFiles > 0 && used + 1 < bodyHeight) {
1467
+ if (shownFiles > 0) {
1454
1468
  body.push(_jsx(Text, { color: DIM, children: '─'.repeat(inner) }, `r-${d.path}`));
1455
1469
  used += 1;
1456
1470
  }
@@ -1468,15 +1482,11 @@ export function DiffPanel({ files, width, height, activity, activityRows = 0 })
1468
1482
  continue;
1469
1483
  }
1470
1484
  for (const [hi, hunk] of d.hunks.entries()) {
1471
- if (used >= bodyHeight)
1472
- break;
1473
- if (hi > 0 && used < bodyHeight) {
1485
+ if (hi > 0) {
1474
1486
  body.push(_jsx(Text, { color: DIM, children: `${' '.repeat(gutter)} ⋯` }, `g-${d.path}-${hi}`));
1475
1487
  used += 1;
1476
1488
  }
1477
1489
  for (const [li, l] of hunk.lines.entries()) {
1478
- if (used >= bodyHeight)
1479
- break;
1480
1490
  const shown = l.kind === 'del' ? l.before : l.after;
1481
1491
  const sign = l.kind === 'add' ? '+' : l.kind === 'del' ? '-' : ' ';
1482
1492
  body.push(_jsxs(Box, { children: [_jsx(Text, { color: DIM, children: String(shown ?? '').padStart(gutter) }), _jsx(Text, { color: l.kind === 'add' ? DIFF_ADD : l.kind === 'del' ? DIFF_DEL : DIM, ...(l.kind !== 'ctx'
@@ -1484,19 +1494,27 @@ export function DiffPanel({ files, width, height, activity, activityRows = 0 })
1484
1494
  used += 1;
1485
1495
  }
1486
1496
  }
1487
- if (d.hiddenLines > 0 && used < bodyHeight) {
1497
+ if (d.hiddenLines > 0) {
1488
1498
  body.push(_jsx(Text, { color: DIM, children: `${' '.repeat(gutter)} ⋯ ${d.hiddenLines} more` }, `m-${d.path}`));
1489
1499
  used += 1;
1490
1500
  }
1491
1501
  shownFiles++;
1492
1502
  used += 1;
1493
- if (used < bodyHeight)
1494
- body.push(_jsx(Text, { children: " " }, `s-${d.path}`));
1503
+ body.push(_jsx(Text, { children: " " }, `s-${d.path}`));
1495
1504
  }
1505
+ /*
1506
+ * Built in full, then windowed — rather than stopping at the height, which is what it used to
1507
+ * do. A panel that only ever builds what fits cannot be scrolled, because the rows below the
1508
+ * fold were never made.
1509
+ */
1510
+ const maxScroll = Math.max(0, body.length - bodyHeight);
1511
+ const from = Math.max(0, Math.min(scroll, maxScroll));
1512
+ const shownRows = body.slice(from, from + bodyHeight);
1496
1513
  const summary = files.length === 0
1497
1514
  ? 'no changes yet'
1498
- : `${files.length} file${files.length === 1 ? '' : 's'} changed`;
1499
- return (_jsxs(Box, { flexDirection: "column", width: width, height: height, borderStyle: "round", borderColor: CYAN, paddingX: 1, flexShrink: 0, overflowY: "hidden", children: [_jsxs(Box, { justifyContent: "space-between", width: inner, children: [_jsxs(Box, { children: [_jsx(Text, { color: INK, bold: true, children: summary }), added > 0 && _jsxs(Text, { color: DIFF_ADD, children: [" +", added] }), removed > 0 && _jsxs(Text, { color: DIFF_DEL, children: [" -", removed] })] }), _jsx(Text, { color: DIM, children: "/diff" })] }), activity && _jsxs(_Fragment, { children: [_jsx(Text, { color: DIM, children: ''.repeat(inner) }), _jsx(Box, { flexDirection: "column", height: Math.max(1, activityRows - 1), overflowY: "hidden", children: activity })] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, flexShrink: 1, overflowY: "hidden", children: body }), shownFiles < files.length && (_jsx(Text, { color: DIM, children: `… ${files.length - shownFiles} more file(s) changed` }))] }));
1515
+ : `${files.length} file${files.length === 1 ? '' : 's'} changed`
1516
+ + (maxScroll > 0 ? ` ${from > 0 ? `↑${from}` : ''}${from < maxScroll ? ` ↓${maxScroll - from}` : ''}`.trimEnd() : '');
1517
+ return (_jsxs(Box, { flexDirection: "column", width: width, height: height, borderStyle: "round", borderColor: CYAN, paddingX: 1, flexShrink: 0, overflowY: "hidden", children: [_jsxs(Box, { justifyContent: "space-between", width: inner, children: [_jsxs(Box, { children: [_jsx(Text, { color: INK, bold: true, children: summary }), added > 0 && _jsxs(Text, { color: DIFF_ADD, children: [" +", added] }), removed > 0 && _jsxs(Text, { color: DIFF_DEL, children: [" -", removed] })] }), _jsx(Text, { color: DIM, children: "/diff" })] }), activity && _jsxs(_Fragment, { children: [_jsx(Text, { color: DIM, children: '─'.repeat(inner) }), _jsx(Box, { flexDirection: "column", height: Math.max(1, activityRows - 1), overflowY: "hidden", children: activity })] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, flexShrink: 1, overflowY: "hidden", children: shownRows }), shownFiles < files.length && (_jsx(Text, { color: DIM, children: `… ${files.length - shownFiles} more file(s) changed` }))] }));
1500
1518
  }
1501
1519
  /**
1502
1520
  * Exported for one reason: so a test can mount it.
@@ -1506,6 +1524,63 @@ export function DiffPanel({ files, width, height, activity, activityRows = 0 })
1506
1524
  * Typechecking passes on that code and no test could reach it, because nothing in the suite mounted
1507
1525
  * an Ink app. Something does now.
1508
1526
  */
1527
+ /**
1528
+ * Where each visual row of the composer begins and ends, as offsets into the draft.
1529
+ *
1530
+ * Not `wrapToWidth`, which normalises runs of whitespace and so cannot be mapped back to the
1531
+ * text it was given. Moving a caret between rows needs the opposite property: every character
1532
+ * accounted for, in its original position, so that row-and-column can be converted to an index
1533
+ * and back without drifting.
1534
+ *
1535
+ * Greedy word wrap, breaking at the last space that fits and hard-splitting a word too long for
1536
+ * a row — the same rule the composer is drawn with, so the rows here are the rows on screen.
1537
+ */
1538
+ export function composerRows(text, width) {
1539
+ const w = Math.max(1, width);
1540
+ const rows = [];
1541
+ let lineStart = 0;
1542
+ for (const line of text.split('\n')) {
1543
+ let from = 0;
1544
+ while (from <= line.length) {
1545
+ if (line.length - from <= w) {
1546
+ rows.push({ start: lineStart + from, end: lineStart + line.length });
1547
+ break;
1548
+ }
1549
+ // The last space that still fits, so a word is not split when it need not be.
1550
+ const slice = line.slice(from, from + w + 1);
1551
+ const space = slice.lastIndexOf(' ');
1552
+ const take = space > 0 ? space : w;
1553
+ rows.push({ start: lineStart + from, end: lineStart + from + take });
1554
+ from += space > 0 ? take + 1 : take; // the break space belongs to neither row
1555
+ }
1556
+ lineStart += line.length + 1; // + the newline
1557
+ }
1558
+ return rows;
1559
+ }
1560
+ /**
1561
+ * The caret one visual row up or down, or null when there is no such row.
1562
+ *
1563
+ * Null is the useful half: with nothing above, Up is free to mean "the previous prompt", which
1564
+ * is what it has always meant and what a shell does. So a one-line draft keeps its history
1565
+ * recall and a wrapped or multi-line one becomes editable in the middle, which is what was asked
1566
+ * for — "must be able to move in lines/rows for easy editing/correcting when need to write in
1567
+ * between".
1568
+ *
1569
+ * The column is kept where it can be and clamped to the end of a shorter row, as every editor
1570
+ * does.
1571
+ */
1572
+ export function caretRowMove(text, caret, width, direction) {
1573
+ const rows = composerRows(text, width);
1574
+ if (rows.length < 2)
1575
+ return null;
1576
+ const here = rows.findIndex((r, i) => caret <= r.end || i === rows.length - 1);
1577
+ const target = here + direction;
1578
+ if (target < 0 || target >= rows.length)
1579
+ return null;
1580
+ const column = caret - rows[here].start;
1581
+ const to = rows[target];
1582
+ return Math.min(to.start + column, to.end);
1583
+ }
1509
1584
  /**
1510
1585
  * The selected span of the composer, or null when nothing is selected.
1511
1586
  *
@@ -2085,6 +2160,23 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
2085
2160
  * reading something further up is not yanked away by the next tool call.
2086
2161
  */
2087
2162
  const [scrollBack, setScrollBack] = useState(0);
2163
+ /**
2164
+ * How far back the diff panel is looking, independently of the conversation.
2165
+ *
2166
+ * Two scroll positions, because there are two things to read and they are not read at the same
2167
+ * pace: following the transcript should not drag a diff away from the hunk being studied, and
2168
+ * studying a diff should not cost your place in the conversation.
2169
+ */
2170
+ const [panelScroll, setPanelScroll] = useState(0);
2171
+ /**
2172
+ * The layout the wheel listener needs, in refs.
2173
+ *
2174
+ * That listener is attached to stdin once and lives for the session, so anything it reads from
2175
+ * the render scope would be whatever the layout was when it was attached. Refs are read at the
2176
+ * moment the wheel turns instead.
2177
+ */
2178
+ const sidePanelOpenRef = useRef(false);
2179
+ const contentWidthRef = useRef(0);
2088
2180
  /**
2089
2181
  * Whether the terminal hands mouse events to KONECK.
2090
2182
  *
@@ -2132,20 +2224,38 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
2132
2224
  useEffect(() => {
2133
2225
  if (!mouse || !altScreen || !process.stdin.isTTY)
2134
2226
  return;
2135
- const WHEEL = /\u001b\[<(\d+);\d+;\d+[Mm]/g;
2227
+ const WHEEL = /\u001b\[<(\d+);(\d+);\d+[Mm]/g;
2136
2228
  const onData = (chunk) => {
2137
2229
  const text = typeof chunk === 'string' ? chunk : chunk.toString('latin1');
2138
2230
  if (!text.includes('\u001b[<'))
2139
2231
  return;
2140
- let up = 0, down = 0;
2232
+ /*
2233
+ * Which half of the screen the pointer is over decides what scrolls.
2234
+ *
2235
+ * The column comes in the same report as the button, and it was being thrown away. With
2236
+ * the panel and the conversation side by side, one shared scroll position meant the wheel
2237
+ * moved whichever of them the code had picked in advance — never the one under the hand.
2238
+ */
2239
+ let up = 0, down = 0, overPanel = false;
2141
2240
  for (let m = WHEEL.exec(text); m !== null; m = WHEEL.exec(text)) {
2142
2241
  const button = Number(m[1]);
2242
+ const column = Number(m[2]);
2143
2243
  if (button === 64)
2144
2244
  up++;
2145
2245
  else if (button === 65)
2146
2246
  down++;
2247
+ else
2248
+ continue;
2249
+ overPanel = sidePanelOpenRef.current && column > contentWidthRef.current;
2147
2250
  }
2148
2251
  WHEEL.lastIndex = 0;
2252
+ if (overPanel) {
2253
+ if (up)
2254
+ setPanelScroll(v => Math.max(0, v - up * 3));
2255
+ if (down)
2256
+ setPanelScroll(v => v + down * 3);
2257
+ return;
2258
+ }
2149
2259
  if (up)
2150
2260
  setScrollBack(v => Math.min(Math.max(0, rows.length - 1), v + up * 3));
2151
2261
  if (down)
@@ -4415,18 +4525,39 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
4415
4525
  addSystem('Usage: `/diff` opens the live panel; `/diff off` closes it.');
4416
4526
  return;
4417
4527
  }
4418
- const want = panel !== 'off';
4419
- setShowDiffPanel(want);
4420
- diffPanelTouchedRef.current = true;
4528
+ /*
4529
+ * Bare `/diff` toggles, as every other switch in here does.
4530
+ *
4531
+ * It used to mean "open", always — so pressing it a second time to put the panel away
4532
+ * did nothing at all, and the only way to close it was to know the word `off`. Reported
4533
+ * as "/diff does open side panel but does not close it", which was precisely true.
4534
+ * `/altscreen`, `/thinking`, `/animate` and `/mouse` have all toggled on a bare call
4535
+ * since they were written; this was the odd one out.
4536
+ */
4421
4537
  /*
4422
4538
  * The side panel needs a fixed frame, and `altScreen: false` is a decision.
4423
4539
  *
4424
- * This used to switch the alternate screen on regardless, which is the same override that
4425
- * was removed from startup for the same reason: it is the expensive path, and somebody who
4426
- * turned it off had already said so. Where it is off, the changes are drawn inline in the
4540
+ * This used to switch the alternate screen on regardless, which is the same override
4541
+ * removed from startup for the same reason: it is the expensive path, and somebody who
4542
+ * turned it off had already said so. Where it is off, changes are drawn inline in the
4427
4543
  * conversation instead — which is where they were before the panel existed.
4428
4544
  */
4429
4545
  const canPin = cfg.altScreen !== false;
4546
+ /*
4547
+ * A bare `/diff` toggles what is on screen, not the flag behind it.
4548
+ *
4549
+ * It used to mean "open", always, so pressing it again to put the panel away did nothing
4550
+ * — reported as "/diff does open side panel but does not close it". Toggling the flag
4551
+ * was not enough either: `showDiffPanel` is true by default while the panel is not
4552
+ * visible at all, so the first press would have closed something that was never open.
4553
+ * What has to flip is what can actually be seen — the panel where there is a frame for
4554
+ * one, the inline changes where there is not.
4555
+ */
4556
+ const showingNow = canPin ? diffPanelOpen : showDiffPanel;
4557
+ const want = panel === 'on' ? true : panel === 'off' ? false : !showingNow;
4558
+ setShowDiffPanel(want);
4559
+ setPanelScroll(0);
4560
+ diffPanelTouchedRef.current = true;
4430
4561
  if (want && canPin && !altScreen)
4431
4562
  setAltScreen(true);
4432
4563
  if (!want && !(cfg.altScreen ?? false)
@@ -5325,6 +5456,17 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
5325
5456
  return;
5326
5457
  }
5327
5458
  // Shift with the arrows, so the plain arrows still move the caret in the composer.
5459
+ /*
5460
+ * Alt with an arrow scrolls the panel; everything else here scrolls the conversation.
5461
+ *
5462
+ * The wheel already picks by where the pointer is, which is the natural gesture, but it
5463
+ * needs `/mouse on`. This is the keyboard equivalent, and it is deliberately a modifier
5464
+ * nothing else in the composer uses, so it cannot be reached by accident mid-sentence.
5465
+ */
5466
+ if (key.meta && (key.upArrow || key.downArrow)) {
5467
+ setPanelScroll(v => Math.max(0, Math.min(2_000, v + (key.upArrow ? -3 : 3))));
5468
+ return;
5469
+ }
5328
5470
  if (key.shift && key.upArrow) {
5329
5471
  setScrollBack(v => Math.min(rows.length - 1, v + 1));
5330
5472
  return;
@@ -5733,11 +5875,45 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
5733
5875
  // The composer used to be append-and-backspace only, so fixing a typo near the start of a
5734
5876
  // long prompt meant deleting everything after it. Everything below is the readline set a
5735
5877
  // shell gives you, so an edit costs one keystroke rather than a retype.
5878
+ /*
5879
+ * Up and down move between the rows of the draft before they reach for history.
5880
+ *
5881
+ * A one-line draft has no row above or below, so `caretRowMove` returns null and Up still
5882
+ * means "the previous prompt" — which is what it has always meant and what a shell does.
5883
+ * Once the draft wraps or contains a newline, the same keys become what they are in every
5884
+ * text box, which is the only way to correct something in the middle of a long prompt
5885
+ * without deleting back to it.
5886
+ */
5736
5887
  const historyDirection = draftHistoryDirection(input, key);
5737
5888
  if (historyDirection) {
5738
5889
  recallDraft(historyDirection);
5739
5890
  return;
5740
5891
  }
5892
+ /*
5893
+ * Up and down move the caret between the rows of the draft.
5894
+ *
5895
+ * They did nothing at all before — history is on Ctrl+P and Ctrl+N, as in a shell — so a
5896
+ * long prompt could only be corrected by deleting back to the mistake. Asked for directly:
5897
+ * "must be able to move in lines/rows for easy editing/correcting when need to write in
5898
+ * between".
5899
+ *
5900
+ * Rows here are visual rows, wrapped exactly as the composer draws them, so the caret goes
5901
+ * where the eye expects rather than to the next newline. With Shift held they extend the
5902
+ * selection instead, which is the same bargain the left and right arrows already make.
5903
+ */
5904
+ if (key.upArrow || key.downArrow) {
5905
+ const moved = caretRowMove(draft, caret, composerTextWidth, key.upArrow ? -1 : 1);
5906
+ if (moved === null)
5907
+ return; // one row: nothing above or below to go to
5908
+ if (key.shift) {
5909
+ if (selAnchor === null)
5910
+ setSelAnchor(caret);
5911
+ }
5912
+ else
5913
+ setSelAnchor(null);
5914
+ setCaret(moved);
5915
+ return;
5916
+ }
5741
5917
  /*
5742
5918
  * Shift with an arrow selects, the way it does in every other text box.
5743
5919
  *
@@ -6103,6 +6279,14 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
6103
6279
  // window empty. A cap is still available through `maxWidth` in config for anyone who
6104
6280
  // prefers a narrow measure on a very wide screen, but nothing is capped by default.
6105
6281
  const uiWidth = computeUiWidth(termCols, configMaxWidth);
6282
+ /**
6283
+ * The width the draft actually wraps at inside the composer.
6284
+ *
6285
+ * The box is `uiWidth - 5` wide, one cell of padding each side, and the "> " marker takes two
6286
+ * more. Caret movement between rows has to use the same number the text is drawn with, or the
6287
+ * caret lands a column or two away from where the eye says it should.
6288
+ */
6289
+ const composerTextWidth = Math.max(10, uiWidth - 9);
6106
6290
  // uiWidth minus the container's paddingX={2} on both sides, and then one column of slack.
6107
6291
  //
6108
6292
  // Without the slack a full-width box draws a line exactly as wide as the terminal. Ink counts
@@ -6135,11 +6319,13 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
6135
6319
  // Read by renderStep, which is defined above this line, so it goes through a ref rather than
6136
6320
  // depending on declaration order.
6137
6321
  diffPanelOpenRef.current = diffPanelOpen;
6322
+ sidePanelOpenRef.current = sidePanelOpen;
6138
6323
  showDiffsRef.current = showDiffPanel;
6139
6324
  const diffPanelWidth = sidePanelOpen
6140
6325
  ? Math.max(34, Math.min(Math.floor(uiWidth * 0.46), 96))
6141
6326
  : 0;
6142
6327
  const contentWidth = uiWidth - diffPanelWidth;
6328
+ contentWidthRef.current = contentWidth;
6143
6329
  const barWidth = contentWidth - 5;
6144
6330
  // Space a rendered reply actually has: the bar, minus the response box border (2), its
6145
6331
  // paddingX={1} (2), and the "ꓘK " prefix plus its gap (3). Getting this even one column
@@ -6716,8 +6902,8 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
6716
6902
  : addProv.step === 'model' ? { label: 'default model', hint: 'optional — enter to skip' }
6717
6903
  : { label: 'repoint ' + addProv.name + '? (y/n)',
6718
6904
  hint: `it ships with KONECK, pointing at ${shadowed?.baseURL}` };
6719
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: CYAN, paddingX: 1, marginTop: 1, width: barWidth, children: [_jsx(Text, { color: CYAN, bold: true, children: "Declare a provider" }), _jsxs(Text, { color: MUTED, children: [ask.hint, " \u00B7 esc to cancel"] }), addProv.name !== '' && (_jsxs(Text, { color: DIM, children: [addProv.name, addProv.url ? ' ' + addProv.url : ''] })), addProv.error && _jsx(Text, { color: CRIMSON, children: addProv.error }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: MUTED, children: [ask.label, ": "] }), _jsx(Text, { color: INK, children: addProv.value }), _jsx(Text, { color: CYAN, children: "\u2588" })] })] }));
6720
- })(), keyPrompt && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AMBER, paddingX: 1, marginTop: 1, width: barWidth, children: [_jsxs(Text, { color: AMBER, bold: true, children: ["API key for ", keyPrompt.provider] }), _jsx(Text, { color: MUTED, children: "Paste it and press enter, or ctrl+v to read the clipboard. Held in memory for this session only; esc to cancel." }), keyPrompt.note && _jsx(Text, { color: CYAN, children: keyPrompt.note }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: MUTED, children: [keyPrompt.env, ": "] }), _jsx(Text, { color: INK, children: '*'.repeat(Math.min(keyPrompt.value.length, 48)) }), _jsx(Text, { color: CYAN, children: "\u2588" }), keyPrompt.value.length > 0 && (_jsxs(Text, { color: DIM, children: [" ", keyPrompt.value.length, " characters"] }))] })] })), ask && (() => {
6905
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: CYAN, paddingX: 1, marginTop: 1, width: barWidth, children: [_jsx(Text, { color: CYAN, bold: true, children: "Declare a provider" }), _jsxs(Text, { color: MUTED, children: [ask.hint, " \u00B7 esc to cancel"] }), addProv.name !== '' && (_jsxs(Text, { color: DIM, children: [addProv.name, addProv.url ? ' ' + addProv.url : ''] })), addProv.error && _jsx(Text, { color: CRIMSON, children: addProv.error }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: MUTED, children: [ask.label, ": "] }), _jsx(Text, { color: INK, children: addProv.value }), _jsx(Cursor, {})] })] }));
6906
+ })(), keyPrompt && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AMBER, paddingX: 1, marginTop: 1, width: barWidth, children: [_jsxs(Text, { color: AMBER, bold: true, children: ["API key for ", keyPrompt.provider] }), _jsx(Text, { color: MUTED, children: "Paste it and press enter, or ctrl+v to read the clipboard. Held in memory for this session only; esc to cancel." }), keyPrompt.note && _jsx(Text, { color: CYAN, children: keyPrompt.note }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: MUTED, children: [keyPrompt.env, ": "] }), _jsx(Text, { color: INK, children: '*'.repeat(Math.min(keyPrompt.value.length, 48)) }), _jsx(Cursor, {}), keyPrompt.value.length > 0 && (_jsxs(Text, { color: DIM, children: [" ", keyPrompt.value.length, " characters"] }))] })] })), ask && (() => {
6721
6907
  let detail = '';
6722
6908
  let isCommand = false;
6723
6909
  try {
@@ -6762,7 +6948,7 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
6762
6948
  : '*type the number, or arrows and enter · esc refuses*',
6763
6949
  ];
6764
6950
  return (_jsx(Box, { marginTop: 1, children: _jsx(Panel, { width: panelWidth(lines, barWidth, 46), color: AMBER, title: `Permission — ${modeSpec(mode).label} mode`, children: lines }) }));
6765
- })()] }), sidePanelOpen && (_jsx(Box, { flexDirection: "column", width: diffPanelWidth, flexShrink: 0, children: diffPanelOpen && _jsx(DiffPanel, { files: liveDiffs, width: diffPanelWidth, height: Math.max(6, frameRows - 6), activityRows: activityPanelOpen ? 4 : 0, activity: activityPanelOpen ? _jsxs(_Fragment, { children: [_jsxs(Text, { color: CYAN, bold: true, children: ["Activity \u00B7 ", fmtElapsed(busyStart.current ? Date.now() - busyStart.current : 0)] }), _jsx(Text, { color: AMBER, wrap: "truncate", children: ask ? 'Waiting for your approval' : liveToolRef.current
6951
+ })()] }), sidePanelOpen && (_jsx(Box, { flexDirection: "column", width: diffPanelWidth, flexShrink: 0, children: diffPanelOpen && _jsx(DiffPanel, { files: liveDiffs, width: diffPanelWidth, scroll: panelScroll, height: Math.max(6, frameRows - 6), activityRows: activityPanelOpen ? 4 : 0, activity: activityPanelOpen ? _jsxs(_Fragment, { children: [_jsxs(Text, { color: CYAN, bold: true, children: ["Activity \u00B7 ", fmtElapsed(busyStart.current ? Date.now() - busyStart.current : 0)] }), _jsx(Text, { color: AMBER, wrap: "truncate", children: ask ? 'Waiting for your approval' : liveToolRef.current
6766
6952
  ? 'Running ' + liveToolRef.current.name : thinkingRef.current.chars > 0
6767
6953
  ? 'Waiting for model · reasoning received' : 'Waiting for model' }), _jsx(Text, { color: MUTED, wrap: "truncate", children: liveToolRef.current?.detail || plan?.steps.find(s => s.state !== 'done')?.text || 'esc to interrupt' })] }) : undefined }) }))] }), _jsx(Box, { marginTop: 1, borderStyle: "round", borderColor: busy ? DIM : CYAN, paddingX: 1, width: uiWidth - 5, flexShrink: 0, children: _jsxs(Text, { wrap: "wrap", children: [_jsxs(Text, { color: CYAN, bold: true, children: [G.caret, " "] }), (() => {
6768
6954
  const sel = selectionRange(selAnchor, caret, draft.length);
@@ -6773,7 +6959,7 @@ export function App({ config: initialConfig, clearFrame, synchronizedFrames = fa
6773
6959
  ? _jsx(Text, { color: INK, children: draft.slice(caret) })
6774
6960
  : caret < draft.length
6775
6961
  ? _jsxs(_Fragment, { children: [_jsx(Text, { backgroundColor: CYAN, color: "#10222A", children: draft[caret] }), _jsx(Text, { color: INK, children: draft.slice(caret + 1) })] })
6776
- : _jsx(Text, { color: CYAN, children: "\u2588" })] }));
6962
+ : _jsx(Cursor, {})] }));
6777
6963
  })()] }) }), copyNotice && _jsx(Text, { color: CYAN, children: copyNotice }), _jsx(Box, { marginTop: 1, paddingX: 1, width: uiWidth - 4, flexShrink: 0, children: _jsxs(Text, { wrap: "truncate", backgroundColor: "#24343B", children: [repaint % 2 === 1 ? '\u200b' : '', _jsx(Text, { color: MUTED, children: "TAB " }), _jsx(Text, { color: INK, children: "Analytics" }), _jsx(Text, { color: MUTED, children: " / " }), _jsx(Text, { color: CYAN, children: "/HELP" }), _jsx(Text, { color: INK, children: " Commands" }), _jsx(Text, { color: MUTED, children: " / SHIFT+TAB " }), _jsx(Text, { color: INK, children: "Mode" }), _jsx(Text, { color: MUTED, children: " / " }), _jsx(Text, { color: statusColor, children: statusLabel.toLowerCase() }), plan && planSummary(plan) && (_jsxs(_Fragment, { children: [_jsx(Text, { color: MUTED, children: " / PLAN: " }), _jsx(Text, { color: CYAN, children: planSummary(plan) })] })), _jsx(Text, { color: MUTED, children: " / MODE: " }), _jsx(Text, { color: mode === 'auto' ? INK : AMBER, children: modeSpec(mode).label }), _jsx(Text, { color: MUTED, children: " / EFFORT: " }), _jsx(Text, { color: effort === 'medium' ? INK : AMBER, children: effort }), autoUpdated && (_jsxs(_Fragment, { children: [_jsx(Text, { color: MUTED, children: " / " }), _jsxs(Text, { color: GREEN, children: [G.ok, " Update installed \u00B7 restart to use it"] })] })), mouse && (_jsxs(_Fragment, { children: [_jsx(Text, { color: MUTED, children: " / " }), _jsx(Text, { color: AMBER, children: "WHEEL: on \u2014 shift to select \u00B7 /mouse off" })] })), _jsx(Text, { color: MUTED, children: " / MODEL: " }), _jsx(Text, { color: INK, children: modelShort }), _jsx(Text, { color: MUTED, children: " / v" }), _jsx(Text, { color: updatePane?.behind ? AMBER : INK, children: VERSION }), updatePane?.behind && _jsx(Text, { color: AMBER, children: " \u2191" }), pasteCount > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { color: MUTED, children: " / " }), _jsxs(Text, { color: AMBER, children: [pasteCount, " paste", pasteCount === 1 ? '' : 's', " held, sent in full"] })] })), ' '.repeat(uiWidth)] }) })] }));
6778
6964
  }
6779
6965
  export async function runInkChatMode(config) {