@simon_he/vue-tui 1.1.1 → 1.1.2

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 (66) hide show
  1. package/README.md +68 -28
  2. package/dist/{TMermaidText-CXm_L969.js → TMermaidText-frVr8Ysb.js} +1 -1
  3. package/dist/{TSelect-CiyMvwl-.js → TSelect-tJ87rKPM.js} +6 -168
  4. package/dist/{TTree-DKGiuIcM.js → TTree-CGdE-CYu.js} +12 -13
  5. package/dist/agent.cjs +9 -5
  6. package/dist/agent.js +15 -1197
  7. package/dist/{block-source-5CQp4tF8.js → block-source-CrlmaBM5.js} +7 -601
  8. package/dist/cli/input.d.ts +8 -0
  9. package/dist/cli/video/ffmpeg-frame-source.d.ts +10 -0
  10. package/dist/cli/video/png-frame-parser.d.ts +4 -0
  11. package/dist/cli/video/raw-frame-parser.d.ts +1 -0
  12. package/dist/cli/video/yt-dlp-frame-source.d.ts +11 -0
  13. package/dist/cli.cjs +142 -33
  14. package/dist/cli.d.cts +1 -1
  15. package/dist/cli.d.ts +1 -1
  16. package/dist/cli.js +167 -37
  17. package/dist/core.js +5 -6
  18. package/dist/create-terminal-app.d.ts +24 -1
  19. package/dist/{debug-logger-ChY_PXVk.js → debug-logger-CmsGI4of.js} +1 -1
  20. package/dist/{dom-renderer-DNzmg2As.js → dom-renderer-DXx8fWzD.js} +2 -3
  21. package/dist/experimental/3d/bun/contributor-avatar-atlas.d.ts +12 -0
  22. package/dist/experimental/3d/bun/png.d.ts +1 -0
  23. package/dist/experimental/3d/bun/terminal-badge-scene.d.ts +11 -0
  24. package/dist/experimental/3d/bun/terminal-badge.wgsl.d.ts +1 -0
  25. package/dist/experimental/3d/bun/webgpu-renderer.d.ts +26 -0
  26. package/dist/experimental/3d/bun.cjs +7271 -0
  27. package/dist/experimental/3d/bun.d.cts +4 -0
  28. package/dist/experimental/3d/bun.d.ts +4 -0
  29. package/dist/experimental/3d/bun.js +7390 -0
  30. package/dist/experimental/video/node.cjs +497 -0
  31. package/dist/experimental/video/node.d.cts +4 -0
  32. package/dist/experimental/video/node.d.ts +4 -0
  33. package/dist/experimental/video/node.js +610 -0
  34. package/dist/experimental.cjs +3064 -567
  35. package/dist/experimental.d.cts +5 -0
  36. package/dist/experimental.d.ts +5 -0
  37. package/dist/experimental.js +1524 -9
  38. package/dist/{create-terminal-DXuZ2fci.js → hyperlink-_1FAj7Wq.js} +403 -2
  39. package/dist/index.js +15 -16
  40. package/dist/{linkify-CuuquMQT.js → linkify-D68T7rdW.js} +164 -3
  41. package/dist/markdown.js +8 -8
  42. package/dist/{mermaid-CWto52Wk.js → mermaid-BNhM1jAZ.js} +1 -1
  43. package/dist/mermaid.js +3 -3
  44. package/dist/observability.js +2 -2
  45. package/dist/{path-suggest-fPzRsgPv.js → path-suggest-Dndu4dTi.js} +1 -1
  46. package/dist/renderer/terminal-graphics.d.ts +1 -0
  47. package/dist/renderer-dom.js +3 -4
  48. package/dist/runtime.js +2 -2
  49. package/dist/terminal-graphics-Bbe83wSr.js +597 -0
  50. package/dist/{tlog-theme-CopRt9SC.js → tlog-theme-Bul2Na3u.js} +1206 -12
  51. package/dist/{trace-CYHDKM1m.js → trace-Bh8WnoMo.js} +1 -1
  52. package/dist/vue/components/T3DViewport.d.ts +473 -0
  53. package/dist/vue/components/TAgentTerminalGraphic.d.ts +13 -0
  54. package/dist/vue/components/TVideo.d.ts +291 -0
  55. package/dist/vue/video/types.d.ts +39 -0
  56. package/dist/vue.js +17 -18
  57. package/package.json +38 -1
  58. package/dist/hyperlink-B35-O-cW.js +0 -403
  59. /package/dist/{ansi-palette-CNXqFciC.js → ansi-palette-CH6jc2Z7.js} +0 -0
  60. /package/dist/{env-DNCzvX8b.js → env-Cl8qmNFN.js} +0 -0
  61. /package/dist/{frame-perf-BBhE-iuS.js → frame-perf-CHpWhbC4.js} +0 -0
  62. /package/dist/{path-BI9W15Zt.js → path-mnSgEpCm.js} +0 -0
  63. /package/dist/{rect-Ng-3eKzF.js → rect-DUpeDfBg.js} +0 -0
  64. /package/dist/{runtime-D77C03RM.js → runtime-Byf8XXOT.js} +0 -0
  65. /package/dist/{terminal-selection-CQYr--26.js → terminal-selection-4W1SJj4c.js} +0 -0
  66. /package/dist/{wheel-scroll-CQ22Hcyj.js → wheel-scroll-DASkEZr-.js} +0 -0
package/README.md CHANGED
@@ -54,20 +54,22 @@ Development, release validation, and documentation builds are run on Node.js 20
54
54
 
55
55
  ## Entry Points
56
56
 
57
- | Import | Stability | Use it for |
58
- | --------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
59
- | `@simon_he/vue-tui` | Public | Browser-safe terminal core, DOM renderer, stable Vue components, and input host plugin factory |
60
- | `@simon_he/vue-tui/core` | Public | Terminal core, buffer-facing types, ANSI/theme/path/hyperlink helpers |
61
- | `@simon_he/vue-tui/renderer/dom` | Public | DOM renderer factory and renderer capabilities |
62
- | `@simon_he/vue-tui/vue` | Advanced | Extended Vue components, composables, router helpers, and Vue runtime internals |
63
- | `@simon_he/vue-tui/runtime` | Advanced | Runtime wiring, selection helpers, and clipboard abstraction |
64
- | `@simon_he/vue-tui/observability` | Advanced | Frame perf store, profiler hooks, and trace helpers |
65
- | `@simon_he/vue-tui/cli` | Public | Node-only headless Vue app runtime, stdin driver, stdout renderer, path provider, recording, and terminal clipboard helpers |
66
- | `@simon_he/vue-tui/markdown` | Public | `TMarkdownText`, `TVirtualMarkdown`, markdown parser and layout helpers, streaming markdown block sources |
67
- | `@simon_he/vue-tui/mermaid` | Public | Optional `beautiful-mermaid` bridge and wrapper for `TMermaidText` |
68
- | `@simon_he/vue-tui/experimental` | Experimental | `TContributionGraph`, `TLineChart`, `TCandlestickChart`, `TPieChart`, `TVirtualList`, `TTranscriptView`, `TLogView`, TLog search/link/minimap companions, append-only log store, and TLog plugins |
69
- | `@simon_he/vue-tui/agent` | Experimental | Agent/console transcript, tool-call header, log, markdown, virtual list, render plane, and overlay component aggregation |
70
- | `@simon_he/vue-tui/agent/mermaid` | Experimental | Agent namespace optional `beautiful-mermaid` bridge and wrapper for `TMermaidText` |
57
+ | Import | Stability | Use it for |
58
+ | ------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------- |
59
+ | `@simon_he/vue-tui` | Public | Browser-safe terminal core, DOM renderer, stable Vue components, and input host plugin factory |
60
+ | `@simon_he/vue-tui/core` | Public | Terminal core, buffer-facing types, ANSI/theme/path/hyperlink helpers |
61
+ | `@simon_he/vue-tui/renderer/dom` | Public | DOM renderer factory and renderer capabilities |
62
+ | `@simon_he/vue-tui/vue` | Advanced | Extended Vue components, composables, router helpers, and Vue runtime internals |
63
+ | `@simon_he/vue-tui/runtime` | Advanced | Runtime wiring, selection helpers, and clipboard abstraction |
64
+ | `@simon_he/vue-tui/observability` | Advanced | Frame perf store, profiler hooks, and trace helpers |
65
+ | `@simon_he/vue-tui/cli` | Public | Node-only headless Vue app runtime, stdin driver, stdout renderer, path provider, recording, and terminal clipboard helpers |
66
+ | `@simon_he/vue-tui/markdown` | Public | `TMarkdownText`, `TVirtualMarkdown`, markdown parser and layout helpers, streaming markdown block sources |
67
+ | `@simon_he/vue-tui/mermaid` | Public | Optional `beautiful-mermaid` bridge and wrapper for `TMermaidText` |
68
+ | `@simon_he/vue-tui/experimental` | Experimental | `T3DViewport`, `TVideo`, charts, `TVirtualList`, `TTranscriptView`, `TLogView`, TLog companions, and append-only log tooling |
69
+ | `@simon_he/vue-tui/experimental/video/node` | Experimental | Node-only lazy FFmpeg frame source plus optional yt-dlp resolver for supported video pages |
70
+ | `@simon_he/vue-tui/experimental/3d/bun` | Experimental | Bun-only raw WGSL/WebGPU Pull renderers, including the vue-tui terminal badge scene |
71
+ | `@simon_he/vue-tui/agent` | Experimental | Agent/console transcript, tool-call header, log, markdown, virtual list, render plane, and overlay component aggregation |
72
+ | `@simon_he/vue-tui/agent/mermaid` | Experimental | Agent namespace optional `beautiful-mermaid` bridge and wrapper for `TMermaidText` |
71
73
 
72
74
  The stable surface is terminal core, DOM rendering, CLI runtime, basic Vue components, markdown APIs, and the optional Mermaid bridge. High-throughput log, virtualization, and agent/console aggregation APIs stay under `/experimental` or `/agent` until their public surface settles; keep those imports isolated in application code. Use `/agent/mermaid` when agent code wants the optional Mermaid wrapper without changing the `/agent` main entrypoint.
73
75
 
@@ -82,6 +84,43 @@ import {
82
84
  } from "@simon_he/vue-tui/experimental";
83
85
  ```
84
86
 
87
+ `T3DViewport` is renderer-agnostic and Pull-based. The bundled WGSL renderer is isolated in the Bun-only entrypoint so browser-safe imports do not load native GPU code:
88
+
89
+ ```ts
90
+ import { T3DViewport } from "@simon_he/vue-tui/experimental";
91
+ import { createTerminalBadge3DRenderer } from "@simon_he/vue-tui/experimental/3d/bun";
92
+
93
+ const renderer = createTerminalBadge3DRenderer();
94
+ ```
95
+
96
+ Install the optional `bun-webgpu` peer, then run the complete direction-E terminal badge example with `bun run run:3d:terminal`. Drag to orbit and use a two-finger trackpad gesture or mouse wheel to zoom. CLI hover steering requires `createStdinDriver({ enableMouseMotion: true })`.
97
+
98
+ #### `experimental/3d/bun` platform requirements
99
+
100
+ | Requirement | Detail |
101
+ | --------------------------- | ---------------------------------------------------- |
102
+ | Runtime | **Bun only** — Node.js and browser are not supported |
103
+ | `bun-webgpu` peer | Must be installed manually: `bun add bun-webgpu` |
104
+ | macOS x64 / arm64 | ✅ Prebuilt binary available |
105
+ | Linux x64 | ✅ Prebuilt binary available |
106
+ | Windows x64 | ✅ Prebuilt binary available |
107
+ | Linux arm64 / musl (Alpine) | ❌ No prebuilt binary — must build from source |
108
+
109
+ > `T3DViewport` itself (from `/experimental`) has zero native dependencies and works everywhere. Only `experimental/3d/bun` requires Bun and the optional peer. `bun-webgpu` is an experimental library; see [bun-webgpu](https://github.com/kommander/bun-webgpu) for current status.
110
+
111
+ #### Terminal graphics protocol requirements
112
+
113
+ `TVideo` and `T3DViewport` automatically negotiate their output format based on the detected terminal:
114
+
115
+ | Terminal capability | Output quality |
116
+ | ----------------------------------- | ---------------------------------------------- |
117
+ | kitty or iTerm2 protocol | Pixel-accurate frames (PNG) |
118
+ | No graphics protocol (any terminal) | `gray8` ASCII art — functional, lower fidelity |
119
+
120
+ `TAgentTerminalGraphic` (mermaid diagrams, KaTeX math, images) requires kitty, iTerm2, or sixel to render visually; without a protocol it shows the `fallback` text prop. Always provide a meaningful `fallback` value so non-graphical terminals still convey the content.
121
+
122
+ > sixel terminals get graphics for `TAgentTerminalGraphic` but ASCII art for `TVideo` / `T3DViewport` — only kitty and iTerm2 support pixel-accurate video and 3D frames. See [docs/platform-contracts.md](./docs/platform-contracts.md) for the full degradation table.
123
+
85
124
  Do not deep import from `@simon_he/vue-tui/dist/...`; only the entry points above are part of the supported package contract.
86
125
 
87
126
  ### Migration: Node Host Adapter Moved To `/cli`
@@ -242,20 +281,21 @@ Unhandled promise rejections stay host-owned by default. Setting `cleanupOnUnhan
242
281
 
243
282
  ## Components
244
283
 
245
- | Area | Import | Components / APIs |
246
- | -------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
247
- | Stable layout | `@simon_he/vue-tui` | `TBox`, `TView` |
248
- | Stable text | `@simon_he/vue-tui` | `TText`, `TLink`, `TLinkifyText` |
249
- | Stable input | `@simon_he/vue-tui` | `TInput`, `TList`, `TSelect` |
250
- | Stable overlay | `@simon_he/vue-tui` | `TDialog` |
251
- | Vue extended | `@simon_he/vue-tui/vue` | `TAnchor`, `TFlex`, `TFlexItem`, `TFlow`, `TRenderPlane`, `TRenderLayer`, `TTransition`, `TInputBox`, `TPathPicker`, `TJsonEditor`, `TMultilineModal`, `TDebugOverlay`, composables, router APIs |
252
- | Markdown | `@simon_he/vue-tui/markdown` | `TMarkdownText`, `TVirtualMarkdown` |
253
- | Mermaid | `@simon_he/vue-tui/mermaid` | `beautifulMermaidRenderer`, `TMermaid`, `TMermaidText`, `TBeautifulMermaidText` |
254
- | Experimental | `@simon_he/vue-tui/experimental` | `TContributionGraph`, `TLineChart`, `TCandlestickChart`, `TPieChart`, `TVirtualList`, `TTranscriptView`, `TLogView`, `TLogSearchBar`, `TLogLinksPanel`, `TLogScrollbar`, `TLogMinimap` |
255
- | Agent console | `@simon_he/vue-tui/agent` | `TAgentTranscript`, `TToolCallView`, `TToolLogView`, `TVirtualMarkdown`, `TVirtualList`, `TRenderPlane` |
256
- | Agent Mermaid | `@simon_he/vue-tui/agent/mermaid` | `beautifulMermaidRenderer`, `TMermaid`, `TMermaidText`, `TBeautifulMermaidText` |
257
- | Runtime | `@simon_he/vue-tui/runtime` | runtime, event, and selection APIs |
258
- | CLI | `@simon_he/vue-tui/cli` | `createTerminalApp`, `createStdoutRenderer`, `createStdinDriver`, Node host adapters |
284
+ | Area | Import | Components / APIs |
285
+ | -------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
286
+ | Stable layout | `@simon_he/vue-tui` | `TBox`, `TView` |
287
+ | Stable text | `@simon_he/vue-tui` | `TText`, `TLink`, `TLinkifyText` |
288
+ | Stable input | `@simon_he/vue-tui` | `TInput`, `TList`, `TSelect` |
289
+ | Stable overlay | `@simon_he/vue-tui` | `TDialog` |
290
+ | Vue extended | `@simon_he/vue-tui/vue` | `TAnchor`, `TFlex`, `TFlexItem`, `TFlow`, `TRenderPlane`, `TRenderLayer`, `TTransition`, `TInputBox`, `TPathPicker`, `TJsonEditor`, `TMultilineModal`, `TDebugOverlay`, composables, router APIs |
291
+ | Markdown | `@simon_he/vue-tui/markdown` | `TMarkdownText`, `TVirtualMarkdown` |
292
+ | Mermaid | `@simon_he/vue-tui/mermaid` | `beautifulMermaidRenderer`, `TMermaid`, `TMermaidText`, `TBeautifulMermaidText` |
293
+ | Experimental | `@simon_he/vue-tui/experimental` | `TVideo`, `TContributionGraph`, `TLineChart`, `TCandlestickChart`, `TPieChart`, `TVirtualList`, `TTranscriptView`, `TLogView`, `TLogSearchBar`, `TLogLinksPanel`, `TLogScrollbar`, `TLogMinimap` |
294
+ | Video adapter | `@simon_he/vue-tui/experimental/video/node` | `createFfmpegVideoFrameSource`, `createYtDlpVideoFrameSource` |
295
+ | Agent console | `@simon_he/vue-tui/agent` | `TAgentTranscript`, `TToolCallView`, `TToolLogView`, `TVirtualMarkdown`, `TVirtualList`, `TRenderPlane` |
296
+ | Agent Mermaid | `@simon_he/vue-tui/agent/mermaid` | `beautifulMermaidRenderer`, `TMermaid`, `TMermaidText`, `TBeautifulMermaidText` |
297
+ | Runtime | `@simon_he/vue-tui/runtime` | runtime, event, and selection APIs |
298
+ | CLI | `@simon_he/vue-tui/cli` | `createTerminalApp`, `createStdoutRenderer`, `createStdinDriver`, Node host adapters |
259
299
 
260
300
  For streaming Mermaid source, pass `streaming` with `final`. When `streaming=true` and `final=false`, transient renderer errors do not replace the last successfully rendered diagram; if no diagram has rendered yet, `incompleteText` is shown until the source becomes renderable or `final=true` surfaces the final error.
261
301
 
@@ -1,4 +1,4 @@
1
- import { EventZIndexContextKey, intersectRect, padEndByCells$1 as padEndByCells, repeatChar, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useTerminal, useTerminalNode, useVisibility, withTextWidthProvider } from "./rect-Ng-3eKzF.js";
1
+ import { EventZIndexContextKey, intersectRect, padEndByCells$1 as padEndByCells, repeatChar, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useTerminal, useTerminalNode, useVisibility, withTextWidthProvider } from "./rect-DUpeDfBg.js";
2
2
  import { computed, defineComponent, getCurrentInstance, h, inject, markRaw, onBeforeUnmount, shallowRef, watch } from "vue";
3
3
 
4
4
  //#region src/vue/components/TMermaidText.ts
@@ -1,9 +1,8 @@
1
- import { getPlaneTerminal } from "./create-terminal-DXuZ2fci.js";
1
+ import { getPlaneTerminal, hasEncodedControl } from "./hyperlink-_1FAj7Wq.js";
2
2
  import { charCellWidth } from "./width-GqllnV8C.js";
3
- import { hasEncodedControl } from "./hyperlink-B35-O-cW.js";
4
- import { DialogContextKey, EventZIndexContextKey, ImeAnchorContextKey, LayoutContextKey, RenderPlaneContextKey, RenderStackKey, TInputPluginsContextKey, TerminalContextKey, forEachTextCellSegment, graphemeRangeAt, hasTextWidthAsciiFastPath, intersectRect, padEndByCells$1 as padEndByCells, repeatChar, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useRenderStack, useTerminal, useTerminalNode, useVisibility, withTextWidthProvider, wrapByCells } from "./rect-Ng-3eKzF.js";
5
- import { TView, mergeStyle } from "./linkify-CuuquMQT.js";
6
- import { isAbsolutePath, normalizeNewlines, normalizePath, resolvePath } from "./path-BI9W15Zt.js";
3
+ import { DialogContextKey, EventZIndexContextKey, ImeAnchorContextKey, LayoutContextKey, RenderPlaneContextKey, RenderStackKey, TInputPluginsContextKey, TerminalContextKey, forEachTextCellSegment, graphemeRangeAt, hasTextWidthAsciiFastPath, intersectRect, repeatChar, sanitizeInlineText, sanitizeTextBlock, sliceByCells, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useRenderStack, useTerminal, useTerminalNode, useVisibility, withTextWidthProvider } from "./rect-DUpeDfBg.js";
4
+ import { TText, TView, mergeStyle } from "./linkify-D68T7rdW.js";
5
+ import { isAbsolutePath, normalizeNewlines, normalizePath, resolvePath } from "./path-mnSgEpCm.js";
7
6
  import { computed, defineComponent, h, inject, nextTick, onBeforeUnmount, onMounted, provide, ref, shallowReactive, shallowRef, watch, watchEffect } from "vue";
8
7
 
9
8
  //#region src/vue/components/TRenderPlane.ts
@@ -462,167 +461,6 @@ function createOverlayFocusStack() {
462
461
  };
463
462
  }
464
463
 
465
- //#endregion
466
- //#region src/vue/components/TText.ts
467
- function fitText(text, max) {
468
- if (max <= 0) return "";
469
- text = sanitizeInlineText(text);
470
- return sliceByCells(text, max);
471
- }
472
- function splitLines(text) {
473
- return sanitizeTextBlock(text).split("\n");
474
- }
475
- function computeDefaultWidth(text) {
476
- const lines = splitLines(text);
477
- let max = 0;
478
- for (const line of lines) max = Math.max(max, textCellWidth(line));
479
- return max;
480
- }
481
- const TText = defineComponent({
482
- name: "TText",
483
- props: {
484
- x: {
485
- type: Number,
486
- required: true
487
- },
488
- y: {
489
- type: Number,
490
- required: true
491
- },
492
- zIndex: {
493
- type: Number,
494
- default: 0
495
- },
496
- value: {
497
- type: String,
498
- required: true
499
- },
500
- w: {
501
- type: Number,
502
- default: void 0
503
- },
504
- h: {
505
- type: Number,
506
- default: void 0
507
- },
508
- style: {
509
- type: Object,
510
- default: void 0
511
- },
512
- clear: {
513
- type: Boolean,
514
- default: true
515
- },
516
- wrap: {
517
- type: Boolean,
518
- default: false
519
- },
520
- depsKey: {
521
- type: null,
522
- default: void 0
523
- }
524
- },
525
- setup(props) {
526
- const { terminal, defaultStyle } = useTerminal();
527
- const layout = useLayout();
528
- const { visible, rootProps } = useVisibility();
529
- const defaultWidth = computed(() => computeDefaultWidth(props.value));
530
- const lines = computed(() => {
531
- const w = props.w ?? defaultWidth.value;
532
- if (w <= 0) return [""];
533
- if (!props.wrap) return splitLines(props.value).map((l) => fitText(l, w));
534
- const safe = sanitizeTextBlock(props.value);
535
- return wrapByCells(safe, w).map((l) => fitText(l, w));
536
- });
537
- const absRect = computed(() => {
538
- const width = props.w ?? defaultWidth.value;
539
- const height = props.h ?? (props.wrap ? lines.value.length || 1 : lines.value.length || 1);
540
- const raw = {
541
- x: props.x,
542
- y: props.y,
543
- w: width,
544
- h: height
545
- };
546
- const translated = translateRect(raw, layout.originX, layout.originY);
547
- if (!layout.clipRect) return translated;
548
- return intersectRect(translated, layout.clipRect) ?? {
549
- x: 0,
550
- y: 0,
551
- w: 0,
552
- h: 0
553
- };
554
- });
555
- const fullRect = computed(() => {
556
- const width = props.w ?? defaultWidth.value;
557
- const height = props.h ?? (props.wrap ? lines.value.length || 1 : lines.value.length || 1);
558
- return translateRect({
559
- x: props.x,
560
- y: props.y,
561
- w: width,
562
- h: height
563
- }, layout.originX, layout.originY);
564
- });
565
- useRenderNode(() => ({
566
- zIndex: props.zIndex,
567
- rect: visible.value ? absRect.value : {
568
- x: 0,
569
- y: 0,
570
- w: 0,
571
- h: 0
572
- },
573
- deps: [
574
- visible.value,
575
- absRect.value,
576
- fullRect.value,
577
- props.value,
578
- props.w,
579
- props.h,
580
- props.wrap,
581
- props.style,
582
- defaultStyle.value,
583
- props.depsKey
584
- ],
585
- paint: (dirtyRows) => {
586
- if (!visible.value) return;
587
- const r = absRect.value;
588
- if (r.w <= 0 || r.h <= 0) return;
589
- const full = fullRect.value;
590
- const style = props.style ?? defaultStyle.value;
591
- const blank = props.clear ? spaces(r.w) : "";
592
- const out = lines.value;
593
- const dx = Math.max(0, Math.floor(r.x - full.x));
594
- const fullY = Math.floor(full.y);
595
- const paintRow = (y) => {
596
- const relY = y - r.y;
597
- if (relY < 0 || relY >= r.h) return;
598
- const i = y - fullY;
599
- if (i < 0 || i >= out.length) {
600
- if (props.clear) terminal.write(blank, {
601
- x: r.x,
602
- y,
603
- style
604
- });
605
- return;
606
- }
607
- const src = out[i] ?? "";
608
- const clipped = dx > 0 ? sliceByCellsRange(src, dx, dx + r.w) : sliceByCells(src, r.w);
609
- terminal.write(padEndByCells(clipped, r.w), {
610
- x: r.x,
611
- y,
612
- style
613
- });
614
- };
615
- if (!dirtyRows) {
616
- for (let i = 0; i < r.h; i++) paintRow(r.y + i);
617
- return;
618
- }
619
- for (const y of dirtyRows) paintRow(y);
620
- }
621
- }));
622
- return () => h("span", rootProps);
623
- }
624
- });
625
-
626
464
  //#endregion
627
465
  //#region src/vue/components/TDialog.ts
628
466
  function clamp$3(n, min, max) {
@@ -1865,7 +1703,7 @@ function isAscii(text) {
1865
1703
  return true;
1866
1704
  }
1867
1705
  const textCellWidth$1 = textCellWidth;
1868
- function padEndByCells$1(text, width) {
1706
+ function padEndByCells(text, width) {
1869
1707
  const cells = textCellWidth$1(text);
1870
1708
  if (cells >= width) return text;
1871
1709
  return text + spaces(width - cells);
@@ -6114,4 +5952,4 @@ const TSelect = defineComponent({
6114
5952
  });
6115
5953
 
6116
5954
  //#endregion
6117
- export { TBox, TCommandPalette, TDialog, TInput, TRenderPlane, TSelect, TText, clamp$1, computeCommandPaletteMatchRanges, createOverlayFocusStack, isCommitMention, isWhitespace, mentionChipStyle, padEndByCells$1 as padEndByCells, resolveOverlayPlacement, sliceByCellsWindow, textCellWidth$1 as textCellWidth };
5955
+ export { TBox, TCommandPalette, TDialog, TInput, TRenderPlane, TSelect, clamp$1, computeCommandPaletteMatchRanges, createOverlayFocusStack, isCommitMention, isWhitespace, mentionChipStyle, padEndByCells, resolveOverlayPlacement, sliceByCellsWindow, textCellWidth$1 as textCellWidth };
@@ -1,16 +1,15 @@
1
- import { TERMINAL_RENDER_PLANES, createTerminal, getPlaneTerminal, resetPlaneRowsForRender, scrollPlaneRows } from "./create-terminal-DXuZ2fci.js";
2
- import { sanitizeDomHref } from "./hyperlink-B35-O-cW.js";
3
- import { DOM_RENDERER_CAPABILITIES, createDomRenderer } from "./dom-renderer-DNzmg2As.js";
4
- import { EventZIndexContextKey, ImeAnchorContextKey, LayoutContextKey, RenderStackKey, TInputPluginsContextKey, TPathPickerProviderContextKey, TerminalContextKey, VisibilityContextKey, clearTextCaches, forEachTextCellSegment, formatInlineCellLine, injectionKey, intersectRect, normalizeCellRect, padEndByCells$1 as padEndByCells, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useTerminal, useTerminalNode, useVisibility, withTextRenderPass } from "./rect-Ng-3eKzF.js";
5
- import { TView, TuiThemeContextKey, clamp, createFrameMailbox, createTheme, defaultActiveStyle, defaultDimStyle, fitCellText, linkifyTextSegments, mergeStyle, repeatToCells, tuiDefaultTheme } from "./linkify-CuuquMQT.js";
6
- import { SUPPRESS_TERMINAL_POINTER_DOWN, SUPPRESS_TERMINAL_POINTER_MOVE, SUPPRESS_TERMINAL_POINTER_UP, createEventManager, createRuntime } from "./runtime-D77C03RM.js";
7
- import { framePerfNow, mergeFramePerfReason } from "./frame-perf-BBhE-iuS.js";
8
- import { createFramePerfStore, createTraceStore } from "./trace-CYHDKM1m.js";
9
- import { envFlag, envString, firstNonEmptyEnv } from "./env-DNCzvX8b.js";
10
- import { createTerminalSelectionController } from "./terminal-selection-CQYr--26.js";
11
- import { createDebugLogger, isDebugEnabled } from "./debug-logger-ChY_PXVk.js";
12
- import { TBox, TInput, TRenderPlane, TText, resolveOverlayPlacement } from "./TSelect-CiyMvwl-.js";
13
- import { applyWheelScroll, createWheelScrollState, resetWheelScrollState } from "./wheel-scroll-CQ22Hcyj.js";
1
+ import { TERMINAL_RENDER_PLANES, createTerminal, getPlaneTerminal, resetPlaneRowsForRender, sanitizeDomHref, scrollPlaneRows } from "./hyperlink-_1FAj7Wq.js";
2
+ import { DOM_RENDERER_CAPABILITIES, createDomRenderer } from "./dom-renderer-DXx8fWzD.js";
3
+ import { EventZIndexContextKey, ImeAnchorContextKey, LayoutContextKey, RenderStackKey, TInputPluginsContextKey, TPathPickerProviderContextKey, TerminalContextKey, VisibilityContextKey, clearTextCaches, forEachTextCellSegment, formatInlineCellLine, injectionKey, intersectRect, normalizeCellRect, padEndByCells$1 as padEndByCells, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useTerminal, useTerminalNode, useVisibility, withTextRenderPass } from "./rect-DUpeDfBg.js";
4
+ import { TText, TView, TuiThemeContextKey, clamp, createFrameMailbox, createTheme, defaultActiveStyle, defaultDimStyle, fitCellText, linkifyTextSegments, mergeStyle, repeatToCells, tuiDefaultTheme } from "./linkify-D68T7rdW.js";
5
+ import { SUPPRESS_TERMINAL_POINTER_DOWN, SUPPRESS_TERMINAL_POINTER_MOVE, SUPPRESS_TERMINAL_POINTER_UP, createEventManager, createRuntime } from "./runtime-Byf8XXOT.js";
6
+ import { framePerfNow, mergeFramePerfReason } from "./frame-perf-CHpWhbC4.js";
7
+ import { createFramePerfStore, createTraceStore } from "./trace-Bh8WnoMo.js";
8
+ import { envFlag, envString, firstNonEmptyEnv } from "./env-Cl8qmNFN.js";
9
+ import { createTerminalSelectionController } from "./terminal-selection-4W1SJj4c.js";
10
+ import { createDebugLogger, isDebugEnabled } from "./debug-logger-CmsGI4of.js";
11
+ import { TBox, TInput, TRenderPlane, resolveOverlayPlacement } from "./TSelect-tJ87rKPM.js";
12
+ import { applyWheelScroll, createWheelScrollState, resetWheelScrollState } from "./wheel-scroll-DASkEZr-.js";
14
13
  import { computed, defineComponent, effectScope, getCurrentInstance, h, inject, nextTick, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, provide, ref, shallowReactive, shallowRef, toRef, watch, watchEffect } from "vue";
15
14
 
16
15
  //#region src/observability/tui-profiler.ts
package/dist/agent.cjs CHANGED
@@ -6281,6 +6281,7 @@ var tAgentTerminalGraphicProps = {
6281
6281
  scrolling: { type: Boolean, default: !1 },
6282
6282
  scrollVersion: { type: Number, default: 0 },
6283
6283
  placementMoveWithoutClear: { type: Boolean, default: !1 },
6284
+ preserveRawWhileRendering: { type: Boolean, default: !1 },
6284
6285
  suspended: { type: Boolean, default: !1 },
6285
6286
  retainRawWhileCovered: { type: Boolean, default: !1 },
6286
6287
  ignoreRawCoverage: { type: Boolean, default: !1 },
@@ -6527,7 +6528,7 @@ var TAgentTerminalGraphic = (0, import_vue14.defineComponent)({
6527
6528
  })), accepted;
6528
6529
  }
6529
6530
  function queueDrawGraphic(output, current, rect, full = rect, options = {}) {
6530
- let clearSequence = resolveClearSequence(current), resizeSequence = resolveResizeSequence(current, rect, full), drawKey = terminalDrawKey(current, rect, clearSequence, resizeSequence), activePrevious = lastDrawnGraphic.value, retainedPrevious = rawClearPendingRepaint.value, previous = activePrevious ?? retainedPrevious, previousIsRetained = activePrevious == null && retainedPrevious != null, previousStillActive = previous ? typeof output.isActive == "function" ? output.isActive(previous.id) : !0 : !1;
6531
+ let clearSequence = resolveClearSequence(current), resizeSequence = resolveResizeSequence(current, rect, full), drawKey = terminalDrawKey(current, rect, clearSequence, resizeSequence), activePrevious = lastDrawnGraphic.value, retainedPrevious = rawClearPendingRepaint.value, previous = activePrevious ?? retainedPrevious, previousIsRetained = activePrevious == null && retainedPrevious != null, previousStillActive = previous ? typeof output.isActive == "function" ? output.isActive(previous.id) : !0 : !1, preservePreviousForAtomicReplace = props.preserveRawWhileRendering && activePrevious != null && !previousIsRetained && previousStillActive;
6531
6532
  if (!previousIsRetained && !options.force && previous?.drawKey === drawKey && previousStillActive)
6532
6533
  return !1;
6533
6534
  let canReusePlacementSequence = previousStillActive && previous?.protocol === current.protocol && previous.sequenceHash === current.sequenceHash && current.protocol === "kitty" && !!resizeSequence, scrollVersion = Math.floor(Number(props.scrollVersion ?? 0)), canMoveWithoutClear = canReusePlacementSequence && !!options.placementMoveWithoutClear;
@@ -6542,7 +6543,7 @@ var TAgentTerminalGraphic = (0, import_vue14.defineComponent)({
6542
6543
  activityVersion: graphicsActivityVersion.value,
6543
6544
  scrollVersion
6544
6545
  }, lastRawSkipScrollKey = "", !1;
6545
- if (previousStillActive && !previousIsRetained && !canReusePlacementSequence) {
6546
+ if (previousStillActive && !previousIsRetained && !canReusePlacementSequence && !preservePreviousForAtomicReplace) {
6546
6547
  if (!queueClearLastGraphic({ markPendingRepaint: !1 }))
6547
6548
  return !1;
6548
6549
  } else
@@ -6559,6 +6560,7 @@ var TAgentTerminalGraphic = (0, import_vue14.defineComponent)({
6559
6560
  sequence: canReusePlacementSequence && resizeSequence ? resizeSequence : current.sequence,
6560
6561
  resizeSequence,
6561
6562
  clearSequence,
6563
+ retainOnClear: !!(props.cacheKey && resizeSequence),
6562
6564
  resizeRedraw: canReusePlacementSequence,
6563
6565
  placementMoveWithoutClear: canMoveWithoutClear,
6564
6566
  allowTextOverlay: options.allowTextOverlay,
@@ -6580,10 +6582,11 @@ var TAgentTerminalGraphic = (0, import_vue14.defineComponent)({
6580
6582
  clearSequence,
6581
6583
  resizeSequence,
6582
6584
  retainOnClear: !!(props.cacheKey && resizeSequence),
6585
+ allowTextOverlay: !!options.allowTextOverlay,
6583
6586
  drawKey,
6584
6587
  activityVersion: graphicsActivityVersion.value,
6585
6588
  scrollVersion
6586
- }, lastRawSkipScrollKey = "", !0) : (lastDrawnGraphic.value = null, rawDrawRejectedKey.value !== drawKey && (rawDrawRejectedKey.value = drawKey, scheduler.invalidate({ priority: "low", reason: "data" })), !1);
6589
+ }, lastRawSkipScrollKey = "", !0) : (preservePreviousForAtomicReplace ? (lastDrawnGraphic.value = activePrevious, queueClearLastGraphic({ markPendingRepaint: !1 })) : lastDrawnGraphic.value = null, rawDrawRejectedKey.value !== drawKey && (rawDrawRejectedKey.value = drawKey, scheduler.invalidate({ priority: "low", reason: "data" })), !1);
6587
6590
  }
6588
6591
  function hasRetainedActiveRawGraphic() {
6589
6592
  let output = graphicsOutput();
@@ -6768,7 +6771,7 @@ var TAgentTerminalGraphic = (0, import_vue14.defineComponent)({
6768
6771
  }
6769
6772
  function scheduleRender(options = {}) {
6770
6773
  let version2 = ++renderVersion;
6771
- if ((options.clearLastGraphic ?? !0) && queueClearLastGraphic(), !builtOnce || !props.streaming) {
6774
+ if ((options.clearLastGraphic ?? !props.preserveRawWhileRendering) && queueClearLastGraphic(), !builtOnce || !props.streaming) {
6772
6775
  builtOnce = !0, renderNow(version2);
6773
6776
  return;
6774
6777
  }
@@ -6795,6 +6798,7 @@ var TAgentTerminalGraphic = (0, import_vue14.defineComponent)({
6795
6798
  () => props.suspendRawWhileScrolling,
6796
6799
  () => props.suspendRenderWhileScrolling,
6797
6800
  () => props.scrolling,
6801
+ () => props.preserveRawWhileRendering,
6798
6802
  () => props.suspended,
6799
6803
  () => props.retainRawWhileCovered,
6800
6804
  () => props.ignoreRawCoverage,
@@ -6898,7 +6902,7 @@ var TAgentTerminalGraphic = (0, import_vue14.defineComponent)({
6898
6902
  let previous = lastDrawnGraphic.value;
6899
6903
  if ((previous ? typeof output.isActive == "function" ? output.isActive(previous.id) : !0 : !1) && previous) {
6900
6904
  let clearSequence = resolveClearSequence(current), resizeSequence = resolveResizeSequence(current, rawRectForPaint, full);
6901
- preserveActiveRawGraphic = rawClearPendingRepaint.value == null && previous.drawKey === terminalDrawKey(current, rawRectForPaint, clearSequence, resizeSequence), allowTextOverlay = retainedRawCoveredByHigherRenderNode(r), forceActiveRawRedraw = preserveActiveRawGraphic && (previous.activityVersion !== graphicsActivityVersion.value || allowTextOverlay);
6905
+ preserveActiveRawGraphic = rawClearPendingRepaint.value == null && previous.drawKey === terminalDrawKey(current, rawRectForPaint, clearSequence, resizeSequence), allowTextOverlay = retainedRawCoveredByHigherRenderNode(r), forceActiveRawRedraw = preserveActiveRawGraphic && (previous.activityVersion !== graphicsActivityVersion.value || previous.allowTextOverlay !== allowTextOverlay);
6902
6906
  }
6903
6907
  }
6904
6908
  let preserveActiveRawGraphicForPaint = preserveActiveRawGraphic, out = rawCanQueueForPaint ? displayLines.value : resolveDisplayLines(!1), clearingRawGraphic = rawClearPendingRepaint.value != null || lastDrawnGraphic.value != null && !preserveActiveRawGraphicForPaint, clearOwnedRegion = preserveActiveRawGraphicForPaint || retainedActiveRawGraphic ? !1 : props.clear || clearingRawGraphic || !!rawCanQueueForPaint, blank = clearOwnedRegion ? spaces(r.w) : "", paintRow = (y) => {