@namzu/cli 8.3.0 → 8.4.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.
Files changed (35) hide show
  1. package/dist/integrations/providers/discover.d.ts.map +1 -1
  2. package/dist/integrations/providers/discover.js +24 -0
  3. package/dist/integrations/providers/discover.js.map +1 -1
  4. package/dist/integrations/providers/oauth.d.ts +14 -3
  5. package/dist/integrations/providers/oauth.d.ts.map +1 -1
  6. package/dist/integrations/providers/oauth.js +14 -3
  7. package/dist/integrations/providers/oauth.js.map +1 -1
  8. package/dist/tui/App.d.ts +1 -17
  9. package/dist/tui/App.d.ts.map +1 -1
  10. package/dist/tui/App.js +82 -48
  11. package/dist/tui/App.js.map +1 -1
  12. package/dist/tui/Markdown.d.ts +14 -0
  13. package/dist/tui/Markdown.d.ts.map +1 -1
  14. package/dist/tui/Markdown.js +31 -4
  15. package/dist/tui/Markdown.js.map +1 -1
  16. package/dist/tui/Transcript.d.ts +18 -2
  17. package/dist/tui/Transcript.d.ts.map +1 -1
  18. package/dist/tui/Transcript.js +48 -13
  19. package/dist/tui/Transcript.js.map +1 -1
  20. package/dist/tui/bottom-spacer.d.ts +22 -8
  21. package/dist/tui/bottom-spacer.d.ts.map +1 -1
  22. package/dist/tui/bottom-spacer.js.map +1 -1
  23. package/dist/tui/live-window.d.ts +97 -0
  24. package/dist/tui/live-window.d.ts.map +1 -0
  25. package/dist/tui/live-window.js +140 -0
  26. package/dist/tui/live-window.js.map +1 -0
  27. package/dist/tui/markdown-block-cache.d.ts +57 -0
  28. package/dist/tui/markdown-block-cache.d.ts.map +1 -0
  29. package/dist/tui/markdown-block-cache.js +74 -0
  30. package/dist/tui/markdown-block-cache.js.map +1 -0
  31. package/dist/tui/markdownParser.d.ts +33 -0
  32. package/dist/tui/markdownParser.d.ts.map +1 -1
  33. package/dist/tui/markdownParser.js +124 -54
  34. package/dist/tui/markdownParser.js.map +1 -1
  35. package/package.json +3 -3
@@ -13,14 +13,41 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
13
13
  * - bullets: a fixed-width marker gutter so wrapped lines hang-indent.
14
14
  */
15
15
  import { Box, Text } from 'ink';
16
- import { parseInline, parseMarkdown } from './markdownParser.js';
16
+ import { memo, useRef } from 'react';
17
+ import { createBlockCache } from './markdown-block-cache.js';
18
+ import { parseInline } from './markdownParser.js';
17
19
  import { theme } from './theme.js';
18
20
  const CODE_COLOR = theme.status.ok;
21
+ /**
22
+ * A message's markdown, parsed incrementally.
23
+ *
24
+ * The cache is per mounted component, so it lives exactly as long as the row
25
+ * it serves and is collected with it — a module-level one would hold every
26
+ * block of every message for the life of the process, which is the shape of
27
+ * the retention problem the transcript already had to solve once.
28
+ *
29
+ * The blocks it returns are reused between renders when their source text has
30
+ * not changed, and {@link BlockView} is memoised on them, so a streaming reply
31
+ * re-renders only the block currently being written. See
32
+ * `markdown-block-cache.ts` for why the key is the block's raw text and why
33
+ * the tail of the document is never stored.
34
+ */
19
35
  export function Markdown({ text, color = theme.text.primary }) {
20
- const blocks = parseMarkdown(text);
36
+ const cache = useRef(undefined);
37
+ cache.current ??= createBlockCache();
38
+ const blocks = cache.current.parse(text);
21
39
  return (_jsx(Box, { flexDirection: "column", children: blocks.map((block, i) => (_jsx(BlockView, { block: block, prev: blocks[i - 1], color: color }, `b-${i}`))) }));
22
40
  }
23
- function BlockView({ block, prev, color, }) {
41
+ /**
42
+ * One block.
43
+ *
44
+ * Memoised on its props, all three of which are stable across a token when the
45
+ * block is: the cache hands back the same `block` and `prev` objects and
46
+ * `color` is a constant. Without this the cache would still save the parse and
47
+ * then throw the saving away — `parseInline` runs here, per span, on every
48
+ * render, and it is the more expensive half.
49
+ */
50
+ const BlockView = memo(function BlockView({ block, prev, color, }) {
24
51
  // One blank line between blocks, except: nothing before the first block,
25
52
  // and consecutive list items stay tight (no gap between bullets).
26
53
  const gap = !prev || (block.type === 'bullet' && prev.type === 'bullet') ? 0 : 1;
@@ -38,7 +65,7 @@ function BlockView({ block, prev, color, }) {
38
65
  default:
39
66
  return (_jsx(Box, { marginTop: gap, children: _jsx(Text, { color: color, wrap: "wrap", children: _jsx(Inline, { spans: parseInline(block.text), color: color }) }) }));
40
67
  }
41
- }
68
+ });
42
69
  const TABLE_MAX_COL = 32;
43
70
  /** Render a markdown table as an aligned grid (header bold + dim rule). */
44
71
  function TableView({ headers, rows, color, }) {
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../../src/tui/Markdown.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../../src/tui/Markdown.tsx"],"names":[],"mappings":"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"}
@@ -8,11 +8,27 @@
8
8
  import type { ReactNode } from 'react';
9
9
  import type { TranscriptMessage } from './types.js';
10
10
  export interface TranscriptProps {
11
- /** Finalized messages — rendered once via <Static> (printed to scrollback). */
11
+ /** Finalized messages, oldest first. */
12
12
  readonly messages: readonly TranscriptMessage[];
13
13
  /** The in-progress streaming message, re-rendered live below the static log. */
14
14
  readonly pending: TranscriptMessage | null;
15
15
  readonly state: 'idle' | 'thinking' | 'tool' | 'awaiting-permission';
16
+ /**
17
+ * How many of `messages` have been handed to scrollback.
18
+ *
19
+ * `messages[0, settled)` go through `<Static>`, which prints a row once and
20
+ * never redraws it; the rest are drawn live and can still change — which is
21
+ * what makes expanding a body already on screen possible at all. The caller
22
+ * decides how many that is, because the answer depends on the terminal's
23
+ * height and on the spacer's arithmetic; see `live-window.ts`. Passing
24
+ * `messages.length` is the everything-is-static behaviour.
25
+ *
26
+ * It must never decrease for a given `resetKey`. `<Static>` counts what it
27
+ * has emitted and renders only past that count, so a shrinking prefix leaves
28
+ * rows unprinted, and a row already drawn live would be printed a second
29
+ * time on its way back out.
30
+ */
31
+ readonly settled: number;
16
32
  /** Bump to reset the static log (e.g. /clear, /resume). */
17
33
  readonly resetKey: number;
18
34
  /**
@@ -23,7 +39,7 @@ export interface TranscriptProps {
23
39
  */
24
40
  readonly header?: ReactNode;
25
41
  }
26
- export declare function Transcript({ messages, pending, state, resetKey, header }: TranscriptProps): import("react/jsx-runtime").JSX.Element;
42
+ export declare function Transcript({ messages, pending, state, settled, resetKey, header, }: TranscriptProps): import("react/jsx-runtime").JSX.Element;
27
43
  /**
28
44
  * Whether a body will be truncated, and so will print a hint naming itself.
29
45
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Transcript.d.ts","sourceRoot":"","sources":["../../src/tui/Transcript.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,WAAW,eAAe;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAA;IAC/C,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,qBAAqB,CAAA;IACpE,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAC3B;AAcD,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,eAAe,2CA2CzF;AA8GD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,OAAO,CAE3E;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,MAAM,EAAE,CAqBjF"}
1
+ {"version":3,"file":"Transcript.d.ts","sourceRoot":"","sources":["../../src/tui/Transcript.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,WAAW,eAAe;IAC/B,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAA;IAC/C,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,qBAAqB,CAAA;IACpE;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAC3B;AAcD,wBAAgB,UAAU,CAAC,EAC1B,QAAQ,EACR,OAAO,EACP,KAAK,EACL,OAAO,EACP,QAAQ,EACR,MAAM,GACN,EAAE,eAAe,2CA2DjB;AA0ID;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,OAAO,CAE3E;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,MAAM,EAAE,CAqBjF"}
@@ -7,28 +7,52 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
7
  * a braille spinner in the gutter while the agent works.
8
8
  */
9
9
  import { Box, Static, Text } from 'ink';
10
- import { useEffect, useState } from 'react';
10
+ import { memo, useEffect, useState } from 'react';
11
11
  import { Markdown } from './Markdown.js';
12
12
  import { theme } from './theme.js';
13
13
  const COLLAPSE_LINES = 6;
14
14
  const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
15
- export function Transcript({ messages, pending, state, resetKey, header }) {
15
+ export function Transcript({ messages, pending, state, settled, resetKey, header, }) {
16
16
  const spinner = useSpinner(state !== 'idle');
17
+ const inScrollback = Math.min(Math.max(settled, 0), messages.length);
17
18
  // The banner is row 0 so it prints to the very top of scrollback; messages
18
19
  // follow it. <Static> renders each row exactly once and never re-renders it,
19
- // keeping memory + per-frame work bounded (the whole transcript was
20
- // previously re-rendered on every spinner tick / token, which OOM'd long
21
- // sessions) and removing flicker.
20
+ // so everything behind the live window costs nothing per frame — the whole
21
+ // transcript was once re-rendered on every spinner tick, which exhausted
22
+ // memory on long sessions.
22
23
  const rows = [
23
24
  ...(header ? [{ kind: 'header' }] : []),
24
- ...messages.map((message, i) => ({
25
+ ...messages.slice(0, inScrollback).map((message, i) => ({
25
26
  kind: 'message',
26
27
  message,
27
28
  prev: messages[i - 1],
28
29
  })),
29
30
  ];
30
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: rows, children: (row) => row.kind === 'header' ? (_jsx(Box, { children: header }, "header")) : (_jsx(MessageRow, { message: row.message, prev: row.prev, spinner: "" }, row.message.id)) }, resetKey), pending ? (_jsx(MessageRow, { message: pending, prev: messages[messages.length - 1], spinner: spinner })) : null, messages.length === 0 && !pending ? (_jsx(Box, { paddingY: 1, children: _jsxs(Text, { color: theme.text.muted, children: ["Type a message to begin \u00B7 ", _jsx(Text, { color: theme.text.secondary, children: "/help" }), " for commands"] }) })) : null] }));
31
+ // The live window. Memoised per row, and that is what keeps this affordable:
32
+ // the spinner ticks about twelve times a second and every tick re-renders
33
+ // this component, so an unmemoised window would re-render its rows — parse
34
+ // their markdown, rebuild their elements — on each one. The rows themselves
35
+ // are unchanged objects between ticks, so the memo holds; the row that just
36
+ // changed is the only one that renders.
37
+ const live = messages.slice(inScrollback);
38
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: rows, children: (row) => row.kind === 'header' ? (_jsx(Box, { children: header }, "header")) : (_jsx(MessageRow, { message: row.message, prev: row.prev, spinner: "" }, row.message.id)) }, resetKey), live.map((message, i) => (_jsx(LiveRow, { message: message, prev: messages[inScrollback + i - 1], spinner: "" }, message.id))), pending ? (_jsx(MessageRow, { message: pending, prev: messages[messages.length - 1], spinner: spinner })) : null, messages.length === 0 && !pending ? (_jsx(Box, { paddingY: 1, children: _jsxs(Text, { color: theme.text.muted, children: ["Type a message to begin \u00B7 ", _jsx(Text, { color: theme.text.secondary, children: "/help" }), " for commands"] }) })) : null] }));
31
39
  }
40
+ /**
41
+ * A row in the live window.
42
+ *
43
+ * Memoised on the whole props object rather than on a hand-picked key. React's
44
+ * default shallow compare over `{message, prev, spinner}` is already exactly
45
+ * "has anything about this row changed": the transcript is held as immutable
46
+ * rows, so an update rebuilds only the rows it touches and leaves every other
47
+ * object identical. A `(id, detailExpanded)` key would be the same answer for
48
+ * two fields and silently the wrong one for every other field a row has.
49
+ *
50
+ * Terminal width is deliberately NOT part of it. Nothing in a row's element
51
+ * tree depends on the width — wrapping is done by the layout engine from the
52
+ * same tree, and a resize re-lays-out without re-rendering — so a width key
53
+ * would be a prop that drives nothing.
54
+ */
55
+ const LiveRow = memo(MessageRow);
32
56
  function MessageRow({ message, prev, spinner, }) {
33
57
  const glyph = message.pending ? spinner : (message.glyph ?? glyphForRole(message.role));
34
58
  // The `⎿` tool-result gutter is rendered dim so the call line leads.
@@ -42,12 +66,23 @@ function MessageRow({ message, prev, spinner, }) {
42
66
  /**
43
67
  * Collapsible tool diff / output, aligned under the content gutter.
44
68
  *
45
- * `expanded` comes from the ROW, not from a view-wide setting, because a
46
- * view-wide setting reaches the wrong rows: `<Static>` renders each item once,
47
- * calling the CURRENT render function for items it has not emitted yet — so a
48
- * flag flipped now applies to rows that have not happened and to none of the
49
- * rows on screen. `/expand` therefore pushes a new row with the flag already
50
- * set, rather than trying to flip one on a row that has been printed.
69
+ * `expanded` comes from the ROW, and that is now load-bearing in the opposite
70
+ * direction from the reason it was written.
71
+ *
72
+ * It used to say that a view-wide setting could not work, because every
73
+ * finalized row went through `<Static>`: that renders each item once and calls
74
+ * the CURRENT render function only for items it has not emitted yet, so a flag
75
+ * flipped now would apply to rows that have not happened and to none of the
76
+ * rows on screen. True of a row in scrollback, and it is why `/expand` pushes a
77
+ * new row carrying the same lines rather than reopening the old one.
78
+ *
79
+ * It is not true of the live window. Those rows are re-rendered from state on
80
+ * every frame, so flipping this flag on one of them redraws that row in place —
81
+ * which is what the expand key now does, for the rows an operator is actually
82
+ * looking at. The flag stays on the row rather than becoming view-wide because
83
+ * the two mechanisms have to coexist: `/expand` still appends for anything that
84
+ * has settled into scrollback, and a view-wide flag would mean something
85
+ * different to each half.
51
86
  */
52
87
  function DetailBlock({ lines, expanded, detailRef, }) {
53
88
  const { shown, hidden } = splitDetail(lines, expanded);
@@ -1 +1 @@
1
- {"version":3,"file":"Transcript.js","sourceRoot":"","sources":["../../src/tui/Transcript.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Transcript.js","sourceRoot":"","sources":["../../src/tui/Transcript.tsx"],"names":[],"mappings":"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"}
@@ -49,17 +49,31 @@ export interface SpacerInput {
49
49
  /** Terminal width, for wrapping. `undefined` falls back to 80. */
50
50
  readonly columns: number | undefined;
51
51
  /**
52
- * The finalized transcript lines, as emitted — before ink renders them.
52
+ * The lines of the transcript that have been printed to scrollback, as
53
+ * emitted — before ink renders them.
53
54
  *
54
- * Every line a row will print, including the collapsed body under a tool
55
- * call. The caller used to pass each row's `content` alone, which counted an
56
- * eight-row tool result as one row: the estimate then ran low by seven, and
57
- * the asymmetry above says exactly what running low costs. `/expand` makes a
58
- * row whose whole substance is its body, so a caller that passed content
59
- * alone would hand a two-hundred-line row over as a single line.
55
+ * Every line such a row will print, including the collapsed body under a
56
+ * tool call. The caller used to pass each row's `content` alone, which
57
+ * counted an eight-row tool result as one row: the estimate then ran low by
58
+ * seven, and the asymmetry above says exactly what running low costs.
59
+ * `/expand` makes a row whose whole substance is its body, so a caller that
60
+ * passed content alone would hand a two-hundred-line row over as a single
61
+ * line.
62
+ *
63
+ * Rows still in the live window belong in {@link liveRows}, not here. They
64
+ * are two different quantities — content above the live region, and the live
65
+ * region's own height — and this one is only the first.
60
66
  */
61
67
  readonly transcript: readonly string[];
62
- /** Rows the live region occupies: activity, composer frame, status bar. */
68
+ /**
69
+ * Rows the live region occupies: the window of transcript rows that are
70
+ * still redrawable, then the activity line, composer frame and status bar.
71
+ *
72
+ * A constant until the live window existed. It is now a function of what is
73
+ * in that window, because an expanded body in it is thirty rows of live
74
+ * region rather than eight, and a spacer that kept assuming the old constant
75
+ * would pad the composer straight off the bottom. See `live-window.ts`.
76
+ */
63
77
  readonly liveRows: number;
64
78
  }
65
79
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"bottom-spacer.d.ts","sourceRoot":"","sources":["../../src/tui/bottom-spacer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,IAAI,CAAA;AAE5B,MAAM,WAAW,WAAW;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,CASR;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAc3D"}
1
+ {"version":3,"file":"bottom-spacer.d.ts","sourceRoot":"","sources":["../../src/tui/bottom-spacer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,IAAI,CAAA;AAE5B,MAAM,WAAW,WAAW;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,CASR;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAc3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"bottom-spacer.js","sourceRoot":"","sources":["../../src/tui/bottom-spacer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAA;AAsB5B;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACpC,UAA6B,EAC7B,OAA2B;IAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA;IACzC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAA;QACrD,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IAClD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAErD,uEAAuE;IACvE,oBAAoB;IACpB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,CAAC,CAAA;IAEvE,MAAM,IAAI,GAAG,qBAAqB,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,QAAQ,GAAG,WAAW,CAAA;IAEhF,2EAA2E;IAC3E,6EAA6E;IAC7E,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,CAAC,CAAA;IAE1B,OAAO,IAAI,GAAG,IAAI,CAAA;AACnB,CAAC"}
1
+ {"version":3,"file":"bottom-spacer.js","sourceRoot":"","sources":["../../src/tui/bottom-spacer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAA;AAoC5B;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACpC,UAA6B,EAC7B,OAA2B;IAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA;IACzC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAA;QACrD,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IAClD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAErD,uEAAuE;IACvE,oBAAoB;IACpB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,CAAC,CAAA;IAEvE,MAAM,IAAI,GAAG,qBAAqB,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,QAAQ,GAAG,WAAW,CAAA;IAEhF,2EAA2E;IAC3E,6EAA6E;IAC7E,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,CAAC,CAAA;IAE1B,OAAO,IAAI,GAAG,IAAI,CAAA;AACnB,CAAC"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * How much of the transcript is still ALIVE — redrawable — and how much has
3
+ * already been handed to the terminal's own scrollback.
4
+ *
5
+ * ## Why there is a window at all
6
+ *
7
+ * Every finalized row used to go straight into `<Static>`, which prints a row
8
+ * once and never redraws it. That kept per-frame work bounded, and it also made
9
+ * changing a row that is already on screen impossible by construction: an
10
+ * expand key could not reopen a collapsed body, so expansion had to become a
11
+ * command that appends a second copy of the output further down.
12
+ *
13
+ * A small window of the most recent rows is kept live instead. Inside it a row
14
+ * can be redrawn in place, so expansion works where an operator actually looks;
15
+ * `/expand <n>` remains the way to reach anything older, and the hint under a
16
+ * collapsed body already degrades correctly when a row has no number.
17
+ *
18
+ * ## Why the window is bounded by HEIGHT, not by a count of rows
19
+ *
20
+ * This is the constraint the whole design turns on, and it is a property of the
21
+ * renderer rather than a preference. When the live region's height reaches the
22
+ * viewport's, ink stops doing an incremental repaint and instead writes
23
+ * `clearTerminal` followed by **the entire static output it has accumulated
24
+ * this session** plus the frame. On a long session that is the whole transcript,
25
+ * re-serialized on every spinner tick — which is the allocation churn that
26
+ * pushed `<Static>` to swallow everything in the first place.
27
+ *
28
+ * So the window takes rows from the end only while their estimated height fits
29
+ * a budget the live furniture and a safety margin are already subtracted from.
30
+ * A single row taller than the budget leaves the window empty, and an empty
31
+ * window is exactly the previous behaviour — the failure direction is "no
32
+ * retroactive expansion", never "repaint the session".
33
+ *
34
+ * ## Why it only ever moves one way
35
+ *
36
+ * `settled` is a floor the caller carries between renders. `<Static>` keeps an
37
+ * index of how many items it has emitted and renders only what is past it, so a
38
+ * shrinking item list would leave rows unprinted; and a row that has already
39
+ * been drawn live must not be handed back to a mechanism that would print it
40
+ * again. Rows therefore leave the window in one direction, oldest first, and a
41
+ * row that has settled never comes back.
42
+ */
43
+ import type { TranscriptMessage } from './types.js';
44
+ /**
45
+ * The most rows the window will ever hold, whatever the terminal's height.
46
+ *
47
+ * A cap on top of the height budget, because the budget alone would put thirty
48
+ * short rows in the live region on a tall terminal — thirty rows re-laid-out
49
+ * per spinner tick to make retroactive expansion available on output nobody is
50
+ * still looking at. Six covers what an operator is working with: a tool call,
51
+ * its result, and the exchange around them.
52
+ */
53
+ export declare const MAX_LIVE_ROWS = 6;
54
+ export interface LiveWindowInput {
55
+ /** Finalized rows, oldest first. The pending row is not one of these. */
56
+ readonly messages: readonly TranscriptMessage[];
57
+ /** Terminal height. `undefined` when not a TTY. */
58
+ readonly rows: number | undefined;
59
+ /** Terminal width, for wrapping. `undefined` falls back to 80. */
60
+ readonly columns: number | undefined;
61
+ /** Rows the live region occupies apart from the window: activity, composer, status bar. */
62
+ readonly furnitureRows: number;
63
+ /** How many rows have already settled into scrollback. The window never reaches back past this. */
64
+ readonly settled: number;
65
+ }
66
+ export interface LiveWindow {
67
+ /** `messages[0, settled)` are in scrollback; the rest are drawn live. */
68
+ readonly settled: number;
69
+ /** The live rows' estimated height, for the bottom spacer to account for. */
70
+ readonly rows: number;
71
+ }
72
+ /**
73
+ * Every line the finalized transcript will print, for a height estimate.
74
+ *
75
+ * Exported so the wiring is testable rather than only typecheckable. The
76
+ * spacer's own docblock states the asymmetry it depends on: over-count the
77
+ * content and the composer merely floats, under-count it and the composer is
78
+ * pushed off the bottom. The caller used to pass each row's `content` alone,
79
+ * which counted a six-line collapsed tool body as nothing at all — the estimate
80
+ * ran low by six per tool call, in the direction that costs the usability
81
+ * rather than the feature. `/expand` makes it acute: a row whose entire
82
+ * substance is a two-hundred-line body would have been handed over as one line.
83
+ *
84
+ * A pending row is excluded because it is not in the static log yet; the
85
+ * spacer's `liveRows` covers the live region.
86
+ */
87
+ export declare function transcriptLines(messages: readonly TranscriptMessage[]): readonly string[];
88
+ /**
89
+ * How much of the transcript stays live, given the room there is for it.
90
+ *
91
+ * Returns `settled === messages.length` — everything in scrollback, nothing
92
+ * redrawable — whenever the answer is not knowable: no TTY, an implausible
93
+ * height, or a most-recent row too tall to hold. That is the previous
94
+ * behaviour, and it is the safe direction.
95
+ */
96
+ export declare function liveWindow(input: LiveWindowInput): LiveWindow;
97
+ //# sourceMappingURL=live-window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-window.d.ts","sourceRoot":"","sources":["../../src/tui/live-window.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,IAAI,CAAA;AAE9B,MAAM,WAAW,eAAe;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAA;IAC/C,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,2FAA2F;IAC3F,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,mGAAmG;IACnG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,UAAU;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACrB;AAmBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,MAAM,EAAE,CAGzF;AA4BD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CAmB7D"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * How much of the transcript is still ALIVE — redrawable — and how much has
3
+ * already been handed to the terminal's own scrollback.
4
+ *
5
+ * ## Why there is a window at all
6
+ *
7
+ * Every finalized row used to go straight into `<Static>`, which prints a row
8
+ * once and never redraws it. That kept per-frame work bounded, and it also made
9
+ * changing a row that is already on screen impossible by construction: an
10
+ * expand key could not reopen a collapsed body, so expansion had to become a
11
+ * command that appends a second copy of the output further down.
12
+ *
13
+ * A small window of the most recent rows is kept live instead. Inside it a row
14
+ * can be redrawn in place, so expansion works where an operator actually looks;
15
+ * `/expand <n>` remains the way to reach anything older, and the hint under a
16
+ * collapsed body already degrades correctly when a row has no number.
17
+ *
18
+ * ## Why the window is bounded by HEIGHT, not by a count of rows
19
+ *
20
+ * This is the constraint the whole design turns on, and it is a property of the
21
+ * renderer rather than a preference. When the live region's height reaches the
22
+ * viewport's, ink stops doing an incremental repaint and instead writes
23
+ * `clearTerminal` followed by **the entire static output it has accumulated
24
+ * this session** plus the frame. On a long session that is the whole transcript,
25
+ * re-serialized on every spinner tick — which is the allocation churn that
26
+ * pushed `<Static>` to swallow everything in the first place.
27
+ *
28
+ * So the window takes rows from the end only while their estimated height fits
29
+ * a budget the live furniture and a safety margin are already subtracted from.
30
+ * A single row taller than the budget leaves the window empty, and an empty
31
+ * window is exactly the previous behaviour — the failure direction is "no
32
+ * retroactive expansion", never "repaint the session".
33
+ *
34
+ * ## Why it only ever moves one way
35
+ *
36
+ * `settled` is a floor the caller carries between renders. `<Static>` keeps an
37
+ * index of how many items it has emitted and renders only what is past it, so a
38
+ * shrinking item list would leave rows unprinted; and a row that has already
39
+ * been drawn live must not be handed back to a mechanism that would print it
40
+ * again. Rows therefore leave the window in one direction, oldest first, and a
41
+ * row that has settled never comes back.
42
+ */
43
+ import { renderedDetailLines } from './Transcript.js';
44
+ import { SAFETY_ROWS, estimateRenderedLines } from './bottom-spacer.js';
45
+ /**
46
+ * The most rows the window will ever hold, whatever the terminal's height.
47
+ *
48
+ * A cap on top of the height budget, because the budget alone would put thirty
49
+ * short rows in the live region on a tall terminal — thirty rows re-laid-out
50
+ * per spinner tick to make retroactive expansion available on output nobody is
51
+ * still looking at. Six covers what an operator is working with: a tool call,
52
+ * its result, and the exchange around them.
53
+ */
54
+ export const MAX_LIVE_ROWS = 6;
55
+ /**
56
+ * Every line one row will print, including the body under a tool call.
57
+ *
58
+ * The blank row `MessageRow` puts above every entry but the first and the `⎿`
59
+ * result rows is counted, because one row per entry is not negligible: forty
60
+ * entries is forty rows, which on most terminals is the whole viewport. The
61
+ * content is indented by the two-column glyph gutter it renders beside, so a
62
+ * long line is measured against the width it actually has.
63
+ */
64
+ function messageLines(message, hasPrev) {
65
+ return [
66
+ ...(hasPrev && message.glyph !== '⎿' ? [''] : []),
67
+ ` ${message.content}`,
68
+ ...renderedDetailLines(message),
69
+ ];
70
+ }
71
+ /**
72
+ * Every line the finalized transcript will print, for a height estimate.
73
+ *
74
+ * Exported so the wiring is testable rather than only typecheckable. The
75
+ * spacer's own docblock states the asymmetry it depends on: over-count the
76
+ * content and the composer merely floats, under-count it and the composer is
77
+ * pushed off the bottom. The caller used to pass each row's `content` alone,
78
+ * which counted a six-line collapsed tool body as nothing at all — the estimate
79
+ * ran low by six per tool call, in the direction that costs the usability
80
+ * rather than the feature. `/expand` makes it acute: a row whose entire
81
+ * substance is a two-hundred-line body would have been handed over as one line.
82
+ *
83
+ * A pending row is excluded because it is not in the static log yet; the
84
+ * spacer's `liveRows` covers the live region.
85
+ */
86
+ export function transcriptLines(messages) {
87
+ const finalized = messages.filter((m) => !m.pending);
88
+ return finalized.flatMap((message, i) => messageLines(message, i > 0));
89
+ }
90
+ /**
91
+ * Rows added to each windowed row's estimate.
92
+ *
93
+ * `estimateRenderedLines` is deliberately an UNDER-count, because for the
94
+ * bottom spacer counting low leaves more apparent room and the safety margin
95
+ * absorbs the difference. Here the asymmetry runs the other way: under-count a
96
+ * live row and the window takes more of the viewport than it was budgeted, and
97
+ * the price of exceeding the viewport is the whole-session repaint this window
98
+ * exists to stay clear of. Over-count and the window merely holds one row
99
+ * fewer.
100
+ *
101
+ * Two per row covers what the line estimate cannot see — the rule a code block
102
+ * draws around itself, the blank line markdown puts between blocks — without
103
+ * needing to model any of it.
104
+ */
105
+ const ROW_HEIGHT_ALLOWANCE = 2;
106
+ /** How tall one row is expected to render, rounded UP. */
107
+ function messageHeight(message, hasPrev, columns) {
108
+ return estimateRenderedLines(messageLines(message, hasPrev), columns) + ROW_HEIGHT_ALLOWANCE;
109
+ }
110
+ /**
111
+ * How much of the transcript stays live, given the room there is for it.
112
+ *
113
+ * Returns `settled === messages.length` — everything in scrollback, nothing
114
+ * redrawable — whenever the answer is not knowable: no TTY, an implausible
115
+ * height, or a most-recent row too tall to hold. That is the previous
116
+ * behaviour, and it is the safe direction.
117
+ */
118
+ export function liveWindow(input) {
119
+ const { messages, rows, columns, furnitureRows, settled } = input;
120
+ const floor = Math.min(Math.max(settled, 0), messages.length);
121
+ if (rows === undefined || !Number.isFinite(rows))
122
+ return { settled: messages.length, rows: 0 };
123
+ const budget = rows - furnitureRows - SAFETY_ROWS;
124
+ if (budget < 1)
125
+ return { settled: messages.length, rows: 0 };
126
+ let height = 0;
127
+ let held = 0;
128
+ for (let i = messages.length - 1; i >= floor && held < MAX_LIVE_ROWS; i--) {
129
+ const message = messages[i];
130
+ if (!message)
131
+ break;
132
+ const next = height + messageHeight(message, i > 0, columns);
133
+ if (next > budget)
134
+ break;
135
+ height = next;
136
+ held += 1;
137
+ }
138
+ return { settled: messages.length - held, rows: height };
139
+ }
140
+ //# sourceMappingURL=live-window.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-window.js","sourceRoot":"","sources":["../../src/tui/live-window.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Parse a growing markdown document without re-parsing what has not changed.
3
+ *
4
+ * ## The cost this removes
5
+ *
6
+ * A streaming assistant reply is one message whose text grows by a token at a
7
+ * time, and the row rendering it re-renders on every one of them. Parsing the
8
+ * whole message each time makes the work quadratic in the reply's length: a
9
+ * forty-block answer is parsed forty blocks deep on every token, when
10
+ * thirty-nine of those blocks are byte-for-byte what they were a token ago.
11
+ *
12
+ * So the document is scanned into top-level blocks — cheap, one pass over the
13
+ * lines — and only the blocks that are new are parsed. The rest come back as
14
+ * **the same objects**, which is the half that matters to the renderer:
15
+ * `BlockView` is memoised, so an unchanged block is not re-rendered, not
16
+ * re-split into inline spans, and not turned into fresh elements either.
17
+ *
18
+ * ## Why raw text is a sound key
19
+ *
20
+ * `parseBlock` reads only the segment it is given: nothing in this markdown
21
+ * subset makes one block's meaning depend on another (there are no
22
+ * reference-style link definitions, which is the construct that would). Same
23
+ * segment ⇒ same block, so a hit cannot differ from a fresh parse. The
24
+ * `markdownParser` docblock states that property; it is the contract this file
25
+ * depends on, and it is why there is no "give up on caching when the document
26
+ * contains X" escape hatch here. There is no such X.
27
+ *
28
+ * ## Why the last two blocks are never cached
29
+ *
30
+ * Not for correctness — a key is a whole segment, so a block whose text grows
31
+ * simply misses under its new text and is parsed. It is to keep the cache from
32
+ * accumulating garbage: a block that is still being written passes through
33
+ * every one of its own prefixes, and storing them would put an entry per TOKEN
34
+ * into a structure meant to hold an entry per block. That is the memory the
35
+ * quadratic parse was costing, moved rather than removed.
36
+ *
37
+ * Two, not one, because the block still being written is not always the last
38
+ * segment. A half-typed table row is not yet a table row — `| 1 | 2` has no
39
+ * closing pipe — so it scans as a paragraph of its own, and the table above it
40
+ * becomes the second-to-last segment while still growing a row at a time. One
41
+ * excluded segment would have cached that table once per row, at increasing
42
+ * size. The line being typed can reach back exactly one segment and no further:
43
+ * it can be absorbed by the block above it, and that block is maximal, so there
44
+ * is nothing for it to reach past.
45
+ *
46
+ * The cost of the wider exclusion is one extra parse per block over the life of
47
+ * the message, against a saving of one per block per token.
48
+ */
49
+ import { type MdBlock } from './markdownParser.js';
50
+ export interface BlockCache {
51
+ /** Blocks of `src`, reusing the block objects of unchanged segments. */
52
+ parse(src: string): MdBlock[];
53
+ /** How many segments are being held. One per completed block. */
54
+ readonly size: number;
55
+ }
56
+ export declare function createBlockCache(): BlockCache;
57
+ //# sourceMappingURL=markdown-block-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-block-cache.d.ts","sourceRoot":"","sources":["../../src/tui/markdown-block-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,EAAE,KAAK,OAAO,EAA0B,MAAM,qBAAqB,CAAA;AAE1E,MAAM,WAAW,UAAU;IAC1B,wEAAwE;IACxE,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAAA;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CAqB7C"}