@opentui/core 0.5.7 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,63 +1,70 @@
1
- # OpenTUI Core
1
+ <!-- Keep the project introduction aligned with the repository README and opentui.com. -->
2
2
 
3
- OpenTUI is a native terminal UI core written in Zig with TypeScript bindings. The native core exposes a C ABI and can be used from any language. OpenTUI powers OpenCode in production today and will also power terminal.shop. It is an extensible core with a focus on correctness, stability, and high performance. It provides a component-based architecture with flexible layout capabilities, allowing you to create complex terminal applications.
3
+ <p align="center">
4
+ <a href="https://opentui.com">
5
+ <img alt="OpenTUI logo" src="https://opentui.com/opentui-logo-auto.svg" width="270" />
6
+ </a>
7
+ </p>
4
8
 
5
- ## Documentation
9
+ <div align="center">
10
+ <a href="https://www.npmjs.com/package/@opentui/core"><img alt="npm version" src="https://img.shields.io/npm/v/@opentui/core?style=flat-square" /></a>
11
+ <a href="https://github.com/anomalyco/opentui/actions/workflows/build-core.yml"><img alt="Core build status" src="https://img.shields.io/github/actions/workflow/status/anomalyco/opentui/build-core.yml?style=flat-square&branch=main" /></a>
12
+ </div>
6
13
 
7
- - [Getting Started](https://opentui.com/docs/getting-started) - API and usage guide
8
- - [Development Guide](docs/development.md) - Building, testing, and contributing
9
- - [Tree-Sitter](https://opentui.com/docs/reference/tree-sitter) - Syntax highlighting integration
10
- - [Renderables](https://opentui.com/docs/core-concepts/renderables) - Understanding the component model
11
- - [Environment Variables](https://opentui.com/docs/reference/env-vars) - Configuration options
14
+ OpenTUI is a library to build terminal user interfaces.
12
15
 
13
- ## Install
16
+ - It is written in Zig.
17
+ - You write TypeScript directly or through React and Solid.
18
+ - You arrange boxes and text with flexbox.
19
+ - You add selects, inputs, and scroll boxes with keyboard and mouse controls.
20
+ - You can play sounds, show images, and render 3D graphics.
14
21
 
15
- ```bash
16
- bun install @opentui/core
17
- ```
22
+ OpenCode uses OpenTUI in production for millions of users.
18
23
 
19
- ## Build
24
+ [Website](https://opentui.com) | [Documentation](https://opentui.com/docs) | [Packages](https://opentui.com/packages)
20
25
 
21
- ```bash
22
- bun run build
23
- ```
26
+ ## OpenTUI Core
24
27
 
25
- This creates platform-specific libraries that are automatically loaded by the TypeScript layer.
28
+ `@opentui/core` supplies the renderer and TypeScript API. You use imperative renderables and events directly. The
29
+ TypeScript packages call native Zig through an internal foreign function interface (FFI) boundary.
26
30
 
27
- ## Examples
31
+ ```typescript
32
+ import { TextRenderable, createCliRenderer } from "@opentui/core"
28
33
 
29
- ```bash
30
- bun install
31
- cd ../examples
32
- bun run dev
34
+ const renderer = await createCliRenderer({ exitOnCtrlC: true })
35
+
36
+ renderer.root.add(new TextRenderable(renderer, { content: "Hello, OpenTUI!" }))
33
37
  ```
34
38
 
35
- ## Benchmarks
39
+ `exitOnCtrlC: true` calls `renderer.destroy()` when the user presses Ctrl+C. The code that creates the renderer must
40
+ call `renderer.destroy()` on every other shutdown path.
36
41
 
37
- Run native performance benchmarks:
42
+ Install the package:
38
43
 
39
44
  ```bash
40
- bun run bench:native
45
+ bun add @opentui/core
41
46
  ```
42
47
 
43
- See [the native benchmark runner](../native/src/bench.zig) for options such as `--filter` and `--mem`.
48
+ Then build your first app with the [quickstart](https://opentui.com/docs/getting-started/quickstart).
44
49
 
45
- NativeSpanFeed TypeScript benchmarks:
50
+ ## Runtime and platform support
46
51
 
47
- - [src/benchmark/native-span-feed-benchmark.md](src/benchmark/native-span-feed-benchmark.md)
52
+ `@opentui/core` runs on Bun 1.3.0 or later, or on Node.js 26.4.0 or later with ECMAScript modules (ESM) and
53
+ `--experimental-ffi`.
48
54
 
49
- ## CLI Renderer
55
+ The native ABI and the generated platform packages, such as `@opentui/core-linux-x64`, are internal distribution
56
+ surfaces, not application APIs.
50
57
 
51
- ### Renderables
58
+ ## AI agent skill
52
59
 
53
- Renderables are hierarchical objects that can be positioned, nested, styled and rendered to the terminal:
60
+ Install the OpenTUI documentation as a skill for your AI coding assistant with [`npx skills`](https://skills.sh):
54
61
 
55
- ```typescript
56
- import { createCliRenderer, TextRenderable } from "@opentui/core"
62
+ ```bash
63
+ npx skills add anomalyco/opentui --skill opentui
64
+ ```
57
65
 
58
- const renderer = await createCliRenderer()
66
+ Add `-g` to install the skill globally.
59
67
 
60
- const obj = new TextRenderable(renderer, { id: "my-obj", content: "Hello, world!" })
68
+ ## License
61
69
 
62
- renderer.root.add(obj)
63
- ```
70
+ OpenTUI is licensed under the [MIT License](https://github.com/anomalyco/opentui/blob/main/LICENSE).
@@ -5965,7 +5965,7 @@ class MouseParser {
5965
5965
  if (type === "down" && button !== 3) {
5966
5966
  this.mouseButtonsPressed.add(button);
5967
5967
  } else if (type === "up") {
5968
- this.mouseButtonsPressed.clear();
5968
+ this.mouseButtonsPressed.delete(button);
5969
5969
  }
5970
5970
  }
5971
5971
  return {
@@ -13120,7 +13120,7 @@ var VisualCursorStruct = defineStruct([
13120
13120
  ["logicalCol", "u32"],
13121
13121
  ["offset", "u32"]
13122
13122
  ]);
13123
- var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1 }, "u8");
13123
+ var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1, "unicode-wide": 3 }, "u8");
13124
13124
  var TerminalMultiplexerEnum = defineEnum({ none: 0, tmux: 1, zellij: 2, screen: 3, unknown: 4 }, "u8");
13125
13125
  var Osc52SupportEnum = defineEnum({ unknown: 0, supported: 1, unsupported: 2 }, "u8");
13126
13126
  var ImageProtocolEnum = defineEnum({ auto: 0, kitty: 1, sixel: 2, blocks: 3 }, "u8");
@@ -13594,6 +13594,14 @@ function selectionBehaviorByte(behavior) {
13594
13594
  function editorLocalSelectionFlags(updateCursor, followCursor, behavior) {
13595
13595
  return ffiBool(updateCursor) | ffiBool(followCursor) << 1 | selectionBehaviorByte(behavior) << 2;
13596
13596
  }
13597
+ function widthMethodCode(widthMethod) {
13598
+ return widthMethod === "wcwidth" ? 0 : widthMethod === "unicode-wide" ? 3 : 1;
13599
+ }
13600
+ function widthMethodFromCode(code) {
13601
+ if (code === 0)
13602
+ return "wcwidth";
13603
+ return code === 3 ? "unicode-wide" : "unicode";
13604
+ }
13597
13605
  function getOpenTUILib(libPath) {
13598
13606
  const resolvedLibPath = libPath || targetLibPath;
13599
13607
  if (!resolvedLibPath) {
@@ -13804,6 +13812,10 @@ function getOpenTUILib(libPath) {
13804
13812
  args: ["u32"],
13805
13813
  returns: "u32"
13806
13814
  },
13815
+ getBufferWidthMethod: {
13816
+ args: ["u32"],
13817
+ returns: "u8"
13818
+ },
13807
13819
  bufferClear: {
13808
13820
  args: ["u32", "buffer"],
13809
13821
  returns: "void"
@@ -15780,7 +15792,8 @@ class FFIRenderLib {
15780
15792
  }
15781
15793
  const width = this.opentui.symbols.getBufferWidth(bufferPtr);
15782
15794
  const height = this.opentui.symbols.getBufferHeight(bufferPtr);
15783
- return new OptimizedBuffer(this, bufferPtr, width, height, { id: "next buffer", widthMethod: "unicode" });
15795
+ const widthMethod = widthMethodFromCode(this.opentui.symbols.getBufferWidthMethod(bufferPtr));
15796
+ return new OptimizedBuffer(this, bufferPtr, width, height, { id: "next buffer", widthMethod });
15784
15797
  }
15785
15798
  getCurrentBuffer(renderer) {
15786
15799
  const bufferPtr = this.opentui.symbols.getCurrentBuffer(renderer);
@@ -15789,7 +15802,8 @@ class FFIRenderLib {
15789
15802
  }
15790
15803
  const width = this.opentui.symbols.getBufferWidth(bufferPtr);
15791
15804
  const height = this.opentui.symbols.getBufferHeight(bufferPtr);
15792
- return new OptimizedBuffer(this, bufferPtr, width, height, { id: "current buffer", widthMethod: "unicode" });
15805
+ const widthMethod = widthMethodFromCode(this.opentui.symbols.getBufferWidthMethod(bufferPtr));
15806
+ return new OptimizedBuffer(this, bufferPtr, width, height, { id: "current buffer", widthMethod });
15793
15807
  }
15794
15808
  rendererSetPaletteState(renderer, palette, defaultForeground, defaultBackground, paletteEpoch) {
15795
15809
  const paletteBuffer = new Uint16Array(palette.length * 4);
@@ -15993,10 +16007,9 @@ class FFIRenderLib {
15993
16007
  if (Number.isNaN(width) || Number.isNaN(height)) {
15994
16008
  console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack);
15995
16009
  }
15996
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
15997
16010
  const idToUse = id || "unnamed buffer";
15998
16011
  const idBytes = this.encoder.encode(idToUse);
15999
- const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, ffiBool(respectAlpha), widthMethodCode, idBytes, idBytes.byteLength);
16012
+ const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, ffiBool(respectAlpha), widthMethodCode(widthMethod), idBytes, idBytes.byteLength);
16000
16013
  if (!bufferPtr) {
16001
16014
  throw new Error(`Failed to create optimized buffer: ${width}x${height}`);
16002
16015
  }
@@ -16386,8 +16399,7 @@ class FFIRenderLib {
16386
16399
  });
16387
16400
  }
16388
16401
  createTextBuffer(widthMethod) {
16389
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
16390
- const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode);
16402
+ const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode(widthMethod));
16391
16403
  if (!bufferPtr) {
16392
16404
  throw new Error(`Failed to create TextBuffer`);
16393
16405
  }
@@ -16789,8 +16801,7 @@ class FFIRenderLib {
16789
16801
  };
16790
16802
  }
16791
16803
  createEditBuffer(widthMethod) {
16792
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
16793
- const bufferPtr = this.opentui.symbols.createEditBuffer(widthMethodCode, this.eventSinkPtr ?? 0);
16804
+ const bufferPtr = this.opentui.symbols.createEditBuffer(widthMethodCode(widthMethod), this.eventSinkPtr ?? 0);
16794
16805
  if (!bufferPtr) {
16795
16806
  throw new Error("Failed to create EditBuffer");
16796
16807
  }
@@ -17145,10 +17156,9 @@ class FFIRenderLib {
17145
17156
  }
17146
17157
  encodeUnicode(text, widthMethod) {
17147
17158
  const textBytes = this.encoder.encode(text);
17148
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
17149
17159
  const outPtrBuffer = new ArrayBuffer(8);
17150
17160
  const outLenBuffer = new ArrayBuffer(8);
17151
- const success = this.opentui.symbols.encodeUnicode(viewOrNull(textBytes), textBytes.byteLength, outPtrBuffer, outLenBuffer, widthMethodCode);
17161
+ const success = this.opentui.symbols.encodeUnicode(viewOrNull(textBytes), textBytes.byteLength, outPtrBuffer, outLenBuffer, widthMethodCode(widthMethod));
17152
17162
  if (!success) {
17153
17163
  return null;
17154
17164
  }
@@ -18599,5 +18609,5 @@ var yoga_default = Yoga;
18599
18609
 
18600
18610
  export { toArrayBuffer, singleton, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, sleep, stringWidth2 as stringWidth, resolveBundledFilePath, DEFAULT_FOREGROUND_RGB, DEFAULT_BACKGROUND_RGB, normalizeIndexedColorIndex, ansi256IndexToRgb, RGBA, normalizeColorValue, hexToRgb, rgbToHex, hsvToRgb, parseColor, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, terminalNamedSingleStrokeKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, getTreeSitterClient, destroyTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, normalizeTerminalPalette, buildTerminalPaletteSignature, decodePasteBytes, stripAnsiSequences, createHostClipboard, createClipboard, ClipboardTarget, createRendererClipboardAdapter, Clipboard, detectLinks, OptimizedBuffer, TextBuffer, SpanInfoStruct, NativeAudioStreamFormat, NativeAudioStreamState, NativeAudioStreamStateNames, NativeAudioStreamCloseReason, NativeAudioStreamState2 as NativeAudioStreamState1, NativeAudioStreamCloseReason2 as NativeAudioStreamCloseReason1, NativeAudioStreamFormat2 as NativeAudioStreamFormat1, NativeClipboardOperationStatus, NativeClipboardStartStatus, NativeClipboardCancelStatus, NativeClipboardCopyStatus, NativeClipboardDestroyStatus, NativeClipboardShutdownStatus, LogLevel2 as LogLevel, NativeMeasureTargetKind, setRenderLibPath, resolveRenderLib, Align, BoxSizing, Dimension, Direction, Display, Edge, Errata, ExperimentalFeature, FlexDirection, Gutter, Justify, LogLevel as LogLevel1, MeasureMode, NodeType, Overflow, PositionType, Unit, Wrap, ALIGN_AUTO, ALIGN_FLEX_START, ALIGN_CENTER, ALIGN_FLEX_END, ALIGN_STRETCH, ALIGN_BASELINE, ALIGN_SPACE_BETWEEN, ALIGN_SPACE_AROUND, ALIGN_SPACE_EVENLY, BOX_SIZING_BORDER_BOX, BOX_SIZING_CONTENT_BOX, DIMENSION_WIDTH, DIMENSION_HEIGHT, DIRECTION_INHERIT, DIRECTION_LTR, DIRECTION_RTL, DISPLAY_FLEX, DISPLAY_NONE, DISPLAY_CONTENTS, EDGE_LEFT, EDGE_TOP, EDGE_RIGHT, EDGE_BOTTOM, EDGE_START, EDGE_END, EDGE_HORIZONTAL, EDGE_VERTICAL, EDGE_ALL, ERRATA_NONE, ERRATA_STRETCH_FLEX_BASIS, ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, ERRATA_ALL, ERRATA_CLASSIC, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, FLEX_DIRECTION_COLUMN, FLEX_DIRECTION_COLUMN_REVERSE, FLEX_DIRECTION_ROW, FLEX_DIRECTION_ROW_REVERSE, GUTTER_COLUMN, GUTTER_ROW, GUTTER_ALL, JUSTIFY_FLEX_START, JUSTIFY_CENTER, JUSTIFY_FLEX_END, JUSTIFY_SPACE_BETWEEN, JUSTIFY_SPACE_AROUND, JUSTIFY_SPACE_EVENLY, LOG_LEVEL_ERROR, LOG_LEVEL_WARN, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE, LOG_LEVEL_FATAL, MEASURE_MODE_UNDEFINED, MEASURE_MODE_EXACTLY, MEASURE_MODE_AT_MOST, NODE_TYPE_DEFAULT, NODE_TYPE_TEXT, OVERFLOW_VISIBLE, OVERFLOW_HIDDEN, OVERFLOW_SCROLL, POSITION_TYPE_STATIC, POSITION_TYPE_RELATIVE, POSITION_TYPE_ABSOLUTE, UNIT_UNDEFINED, UNIT_POINT, UNIT_PERCENT, UNIT_AUTO, WRAP_NO_WRAP, WRAP_WRAP, WRAP_WRAP_REVERSE, Config, Node, exports_yoga, yoga_default };
18601
18611
 
18602
- //# debugId=CCD1F52D948CB76B64756E2164756E21
18603
- //# sourceMappingURL=chunk-bun-xmsp0nqq.js.map
18612
+ //# debugId=629581C67E2214E264756E2164756E21
18613
+ //# sourceMappingURL=chunk-bun-2956gvaq.js.map