Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
163 commits
Select commit Hold shift + click to select a range
074d610
initial native image api
kommander Jun 11, 2026
b6c8cfa
requirements
kommander Jun 11, 2026
cf294f7
full image format support
kommander Jun 11, 2026
076d6e5
finish
kommander Jun 11, 2026
7cb4f86
demo
kommander Jun 11, 2026
6a14a5d
rename
kommander Jun 11, 2026
621b4e6
update image
kommander Jun 11, 2026
86289e0
fit
kommander Jun 11, 2026
ead5bc0
sixel + kitty graphics
kommander Jun 11, 2026
b1acc3a
detection precedence
kommander Jun 11, 2026
a996891
positive semantics
kommander Jun 11, 2026
828844d
protocol
kommander Jun 11, 2026
c203d2b
sixel dither
kommander Jun 11, 2026
7a9aa27
proper dithering
kommander Jun 11, 2026
0f64080
docs
kommander Jun 11, 2026
276ecfe
perf but bad
kommander Jun 11, 2026
fec8302
meh
kommander Jun 11, 2026
7a5ed36
tss
kommander Jun 11, 2026
d122bc0
sixel fix
kommander Jun 11, 2026
e8c90ee
bench
kommander Jun 11, 2026
ff21eba
avoid retransmission for overlay updates
kommander Jun 11, 2026
6445c0d
no bayer
kommander Jun 12, 2026
8428416
kitty perf
kommander Jun 12, 2026
2490fea
png qual
kommander Jun 12, 2026
04ca279
agnostic drawImage
kommander Jun 13, 2026
edd925b
demo show quality
kommander Jun 14, 2026
3c1f4db
sixel placement opacity
kommander Jul 3, 2026
ac0e420
jpeg exif orientation
kommander Jul 3, 2026
99e8ac8
image and video coverage
kommander Jul 3, 2026
9ad3489
isolate stb resize shim from ubsan
kommander Jul 3, 2026
db4c117
placement level image invalidation
kommander Jul 3, 2026
05ebef7
downscale large kitty transmissions
kommander Jul 3, 2026
2c3b04c
mutable video source and image callbacks
kommander Jul 3, 2026
d38cf2a
add image intrinsics for solid and react
kommander Jul 21, 2026
8643fcb
normalize image ffi boolean
kommander Jul 21, 2026
a665e8f
cover image support in node packaging
kommander Jul 21, 2026
e66a9c6
name image replacement benchmarks precisely
kommander Jul 21, 2026
6cc513a
harden image coverage and cleanup
kommander Jul 21, 2026
d36c8c4
link x64 webp runtime dispatch
kommander Jul 21, 2026
d15992b
docs: document native images
kommander Jul 21, 2026
fd9f6c2
fix image placement rendering
kommander Jul 21, 2026
29a61c7
fix node image test assertions
kommander Jul 21, 2026
8b8d4c4
fix image transparency metadata
kommander Jul 21, 2026
cf76f40
fix zero resolution image fallback
kommander Jul 21, 2026
11d26b5
bound HTTP image downloads
kommander Jul 21, 2026
0e14f15
avoid duplicate image source loads
kommander Jul 21, 2026
40392db
crop kitty image transmissions
kommander Jul 21, 2026
778c4e5
avoid allocations for image-free buffer copies
kommander Jul 22, 2026
8b4c035
enable x64 webp runtime simd
kommander Jul 22, 2026
eb26c75
preserve png passthrough across clones
kommander Jul 22, 2026
1ed4046
normalize unsupported image url schemes
kommander Jul 22, 2026
8cf2909
trim vendored webp decoder sources
kommander Jul 22, 2026
02bf037
harden native image edge cases
kommander Jul 22, 2026
654f492
fix image lifecycle edge cases
kommander Jul 22, 2026
ff121d1
make colon path test permission safe
kommander Jul 22, 2026
f39cadb
strengthen native image behavior tests
kommander Jul 24, 2026
f0089ae
strengthen terminal image protocol tests
kommander Jul 24, 2026
ac2a47c
test image load cancellation lifecycle
kommander Jul 24, 2026
b921a52
tighten react image diagnostics tests
kommander Jul 24, 2026
1854ad1
test solid image replacement lifecycle
kommander Jul 24, 2026
bb53ba2
support blob and response image sources
kommander Jul 24, 2026
97f0ea9
add zero-copy image pixel transfer
kommander Jul 24, 2026
363a3f2
update native image documentation
kommander Jul 24, 2026
391e291
benchmark alpha planes over image markers
kommander Jul 24, 2026
9a7a792
stash overlay
kommander Jul 24, 2026
e37f705
make image overlay demo movable
kommander Jul 26, 2026
dd66b4c
fix(core): harden native image rendering
kommander Jul 28, 2026
e3f7a08
build: include native image notices
kommander Jul 28, 2026
46b4a2e
test(core): pin packed native image runtime
kommander Jul 28, 2026
4885860
fix(core): preserve native image API contracts
kommander Jul 28, 2026
be788f4
docs: remove image loading requirements
kommander Jul 28, 2026
44cc13f
docs: tighten native image guidance
kommander Jul 28, 2026
ac4b9ad
perf(core): benchmark native image overlap paths
kommander Jul 28, 2026
af76e81
perf(core): preserve no-image fast paths
kommander Jul 28, 2026
2bc541a
build(core): make image vendors reproducible
kommander Jul 29, 2026
c622658
fix(core): publish feed frames atomically
kommander Jul 29, 2026
d634129
fix(core): bound image response buffering
kommander Jul 29, 2026
43ea12d
fix(core): stage image state before output
kommander Jul 29, 2026
49be35c
docs: clarify mixed image protocol overlap
kommander Jul 29, 2026
fa92cda
perf(core): index native image placement state
kommander Jul 29, 2026
9f6e96d
fix(core): avoid redundant Sixel image copies
kommander Jul 29, 2026
da64567
docs(core): document stb sanitizer exception
kommander Jul 29, 2026
db57927
fix(core): report image benchmark confidence data
kommander Jul 29, 2026
6fd4c86
fix(core): discard failed image frames
kommander Jul 30, 2026
69cdbb1
test(core): cover feed shutdown under backpressure
kommander Jul 30, 2026
872abb7
docs(core): correct feed teardown ownership
kommander Jul 30, 2026
ba43a85
fix(core): preserve failed split output batches
kommander Jul 30, 2026
3c51489
fix(core): retry unpublished terminal controls
kommander Jul 30, 2026
1ce65bc
fix(core): restore optional image defaults
kommander Jul 30, 2026
6e8554a
fix(solid): cancel image loads on unmount
kommander Jul 30, 2026
9d55b7e
fix(core): reject invalid image option names
kommander Jul 30, 2026
0213cdb
build(core): retain resize pointer sanitizer
kommander Jul 30, 2026
cf313b2
docs: align native image behavior
kommander Jul 30, 2026
8584e26
refactor(core): simplify image load state
kommander Jul 30, 2026
43c4e4e
test(core): cover native image integration paths
kommander Jul 30, 2026
9508026
test(core): cover high-level Sixel selection
kommander Jul 30, 2026
aacdd7d
test(core): cover native image option variants
kommander Jul 30, 2026
e96205b
fix(core): restore failed split repaint state
kommander Jul 30, 2026
0a3a398
test(core): harden native image integration coverage
kommander Jul 30, 2026
e7a5c48
fix(core): restore failed render transitions
kommander Jul 30, 2026
9530319
fix(core): publish hit grids with frames
kommander Jul 30, 2026
e5f8229
test(core): strengthen image behavior assertions
kommander Jul 30, 2026
455c17d
docs(core): pin stb sanitizer exception scope
kommander Jul 30, 2026
63a17fa
fix(core): keep split footer images pinned
kommander Jul 30, 2026
7dc4971
feat(core): render images in split scrollback
kommander Jul 30, 2026
b377f3c
fix(core): avoid upscaling Kitty scrollback images
kommander Jul 30, 2026
17c7b0a
fix(core): reject stale scrollback geometry
kommander Jul 30, 2026
9dc6eaa
fix(core): blend tall scrollback Sixel images
kommander Jul 30, 2026
e37e4bb
test(core): cover pinned native image repaint
kommander Jul 30, 2026
fd498ad
fix(core): restore Kitty history IDs on failure
kommander Jul 30, 2026
61de91d
fix(core): invalidate image resolution on resize
kommander Jul 30, 2026
f5bd169
fix(solid): reset removed style properties
kommander Jul 30, 2026
f4602b3
clipboard: define service contracts
simonklee Jun 19, 2026
f2315e8
clipboard: add asynchronous host service
simonklee Jun 26, 2026
677b6f3
clipboard: add Wayland host support
simonklee Jun 26, 2026
94aae04
clipboard: add nonblocking X11 initialization
simonklee Jun 26, 2026
ad829da
clipboard: add X11 host support
simonklee Jun 26, 2026
73a076f
clipboard: add macOS and Windows support
simonklee Jun 29, 2026
acf32cb
clipboard: harden cross-platform behavior
simonklee Jul 4, 2026
f162961
clipboard: preserve borrowed FFI buffer ownership
simonklee Jul 4, 2026
481795f
clipboard: harden native operation state machines
simonklee Jul 4, 2026
3abc034
renderer: scope terminal keepalive to process stdin
simonklee Jul 4, 2026
3a2d82c
examples: enforce clipboard read limits
simonklee Jul 4, 2026
2b053c9
clipboard: guard Linux-only poll calls
simonklee Jul 4, 2026
af44055
clipboard: read Windows DIB images as PNG
simonklee Jul 5, 2026
fb9a783
clipboard: support WSLg text and image reads
simonklee Jul 6, 2026
4e9df23
clipboard: harden native operation lifecycle
simonklee Jul 7, 2026
62c020c
clipboard: group implementation by subsystem
simonklee Jul 7, 2026
87c0537
clipboard: avoid SIGPIPE on closed provider pipe
simonklee Jul 8, 2026
2b12311
clipboard: harden native operation cleanup
simonklee Jul 9, 2026
1f72623
clipboard: simplify platform lifecycle handling
simonklee Jul 9, 2026
5c9328c
clipboard: honor explicit seat after overflow
simonklee Jul 9, 2026
ea3f3c8
clipboard: fix stale Wayland selection reads
simonklee Jul 10, 2026
268d38d
clipboard: treat empty Wayland text as success
simonklee Jul 10, 2026
cdc36ad
clipboard: convert macOS TIFF to PNG
simonklee Jul 14, 2026
0ab1500
clipboard: fix cross-platform backend edge cases
simonklee Jul 16, 2026
524a648
add missing guards
simonklee Jul 17, 2026
855f883
clipboard: fix cross-platform native tests
simonklee Jul 17, 2026
cea69ec
fixup! clipboard: fix cross-platform native tests
simonklee Jul 17, 2026
e226e59
clipboard: fix abort and backend edge cases
simonklee Jul 27, 2026
7a6f116
clipboard: fix test fixture type narrowing
simonklee Jul 27, 2026
434fac4
fix(core): cancel pre-aborted image responses
kommander Jul 31, 2026
b9f4154
fix(core): normalize image draw ffi boolean
kommander Jul 31, 2026
c3b3395
fix(core): dump native image fallback cells
kommander Jul 31, 2026
3907bad
docs(core): clarify scrollback image fallback
kommander Jul 31, 2026
02983ba
test(core): cover native image release ownership
kommander Jul 31, 2026
87d93ef
fix(core): preserve image context type compatibility
kommander Jul 31, 2026
08ef798
fix(core): pass dump timestamps as bigint
kommander Jul 31, 2026
9271359
test(core): respect node dump permissions
kommander Jul 31, 2026
a883fe0
fix(core): split cell runs around images (#1310)
simonklee Jul 31, 2026
2f37664
refactor(core): simplify Kitty image IDs
kommander Jul 31, 2026
d406e1e
test(core): trim redundant image coverage
kommander Jul 31, 2026
40db847
test(core): cover PNG color policy
kommander Jul 31, 2026
e95c2d2
test(core): cover animated WebP rejection
kommander Jul 31, 2026
a37c987
test(core): pin decoded image limits
kommander Jul 31, 2026
9882711
test(core): cover queued scrollback images
kommander Jul 31, 2026
907607e
test(core): exercise legacy image contexts
kommander Jul 31, 2026
57ec547
docs(core): correct graphics environment metadata
kommander Jul 31, 2026
4fed6c6
docs(examples): correct image protocol status
kommander Jul 31, 2026
64729f0
docs(core): clarify covered Sixel scrollback
kommander Jul 31, 2026
5856523
chore(core): combine native image and clipboard
simonklee Jul 31, 2026
2b2e51e
test(core): cover clipboard image integration
simonklee Jul 29, 2026
8e55419
docs: document host clipboard integration
simonklee Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/bench-native-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
working-directory: packages/core
run: |
set -euo pipefail
output="$(bun run bench:native --mem --filter "UTF-8 Operations" --bench "isAsciiOnly: ASCII text (1KB)" --json)"
output="$(bun run bench:native --mem --filter "Terminal Image" --bench "Kitty cover placement" --json)"
printf '%s\n' "$output"
OUTPUT="$output" bun -e '
const output = process.env.OUTPUT ?? ""
Expand All @@ -67,13 +67,17 @@ jobs:
if (!jsonLine) throw new Error("Native benchmark smoke test produced no JSON output")

const data = JSON.parse(jsonLine)
if (data.benchmark !== "UTF-8 Operations") {
if (data.benchmark !== "Terminal Image") {
throw new Error(`Unexpected benchmark category: ${data.benchmark}`)
}
if (!Array.isArray(data.results) || data.results.length !== 1) {
throw new Error(`Expected exactly one benchmark result, got ${data.results?.length ?? 0}`)
}
if (data.results[0].name !== "isAsciiOnly: ASCII text (1KB)") {
const result = data.results[0]
if (result.name !== "Kitty cover placement") {
throw new Error(`Unexpected benchmark result: ${data.results[0].name}`)
}
if (!Number.isFinite(result.stddev_ns) || !Number.isFinite(result.rme_95)) {
throw new Error(`Benchmark result is missing confidence fields: ${JSON.stringify(result)}`)
}
'
22 changes: 22 additions & 0 deletions .github/workflows/build-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,24 @@ jobs:
echo ""
ls -lah packages/examples/dist/*/

- name: Stage example license notices
run: |
set -e
mkdir -p artifacts/example-notices
cp LICENSE artifacts/example-notices/LICENSE
cp packages/core/src/zig/vendor/wuffs/LICENSE artifacts/example-notices/LICENSE-WUFFS
cp packages/core/src/zig/vendor/stb/LICENSE artifacts/example-notices/LICENSE-STB
cp packages/core/src/zig/vendor/libwebp/COPYING artifacts/example-notices/LICENSE-LIBWEBP
cp packages/core/src/zig/vendor/libwebp/PATENTS artifacts/example-notices/PATENTS-LIBWEBP
cp packages/core/src/zig/vendor/libwebp/AUTHORS artifacts/example-notices/AUTHORS-LIBWEBP

# Create separate zips for each platform's examples
- name: Package examples - darwin-x64
run: |
set -e
mkdir -p artifacts/examples-darwin-x64
cp packages/examples/dist/darwin-x64/opentui-examples artifacts/examples-darwin-x64/
cp artifacts/example-notices/* artifacts/examples-darwin-x64/
cd artifacts
zip -r examples-darwin-x64.zip examples-darwin-x64/
test -f examples-darwin-x64.zip || (echo "❌ Failed to create darwin-x64 zip" && exit 1)
Expand All @@ -142,6 +154,7 @@ jobs:
set -e
mkdir -p artifacts/examples-darwin-arm64
cp packages/examples/dist/darwin-arm64/opentui-examples artifacts/examples-darwin-arm64/
cp artifacts/example-notices/* artifacts/examples-darwin-arm64/
cd artifacts
zip -r examples-darwin-arm64.zip examples-darwin-arm64/
test -f examples-darwin-arm64.zip || (echo "❌ Failed to create darwin-arm64 zip" && exit 1)
Expand All @@ -153,6 +166,7 @@ jobs:
set -e
mkdir -p artifacts/examples-linux-x64
cp packages/examples/dist/linux-x64/opentui-examples artifacts/examples-linux-x64/
cp artifacts/example-notices/* artifacts/examples-linux-x64/
cd artifacts
zip -r examples-linux-x64.zip examples-linux-x64/
test -f examples-linux-x64.zip || (echo "❌ Failed to create linux-x64 zip" && exit 1)
Expand All @@ -164,6 +178,7 @@ jobs:
set -e
mkdir -p artifacts/examples-windows-x64
cp packages/examples/dist/windows-x64/opentui-examples.exe artifacts/examples-windows-x64/
cp artifacts/example-notices/* artifacts/examples-windows-x64/
cd artifacts
zip -r examples-windows-x64.zip examples-windows-x64/
test -f examples-windows-x64.zip || (echo "❌ Failed to create windows-x64 zip" && exit 1)
Expand All @@ -178,6 +193,13 @@ jobs:
test -f artifacts/examples-darwin-arm64.zip || (echo "❌ examples-darwin-arm64.zip missing!" && exit 1)
test -f artifacts/examples-linux-x64.zip || (echo "❌ examples-linux-x64.zip missing!" && exit 1)
test -f artifacts/examples-windows-x64.zip || (echo "❌ examples-windows-x64.zip missing!" && exit 1)
for directory in artifacts/examples-{darwin-x64,darwin-arm64,linux-x64,windows-x64}; do
test -f "$directory/LICENSE-LIBWEBP" || (echo "❌ libwebp notice missing from $directory" && exit 1)
test -f "$directory/PATENTS-LIBWEBP" || (echo "❌ libwebp patents missing from $directory" && exit 1)
test -f "$directory/AUTHORS-LIBWEBP" || (echo "❌ libwebp authors missing from $directory" && exit 1)
test -f "$directory/LICENSE-STB" || (echo "❌ stb notice missing from $directory" && exit 1)
test -f "$directory/LICENSE-WUFFS" || (echo "❌ Wuffs notice missing from $directory" && exit 1)
done

echo ""
echo "✅ All artifacts verified. Ready to upload:"
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/build-native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,24 @@ jobs:

echo "✅ All required build outputs verified (8 native targets, 7 package dists)"

- name: Stage native license notices
run: |
set -e
mkdir -p artifacts/native-notices
cp LICENSE artifacts/native-notices/LICENSE
cp packages/core/src/zig/vendor/wuffs/LICENSE artifacts/native-notices/LICENSE-WUFFS
cp packages/core/src/zig/vendor/stb/LICENSE artifacts/native-notices/LICENSE-STB
cp packages/core/src/zig/vendor/libwebp/COPYING artifacts/native-notices/LICENSE-LIBWEBP
cp packages/core/src/zig/vendor/libwebp/PATENTS artifacts/native-notices/PATENTS-LIBWEBP
cp packages/core/src/zig/vendor/libwebp/AUTHORS artifacts/native-notices/AUTHORS-LIBWEBP

# Create separate zips for each platform's native binaries
- name: Package native binaries - darwin-x64
run: |
set -e
mkdir -p artifacts/native-darwin-x64
cp packages/core/node_modules/@opentui/core-darwin-x64/libopentui.dylib artifacts/native-darwin-x64/
cp artifacts/native-notices/* artifacts/native-darwin-x64/
cd artifacts
zip -r native-darwin-x64.zip native-darwin-x64/
test -f native-darwin-x64.zip || (echo "❌ Failed to create darwin-x64 zip" && exit 1)
Expand All @@ -118,6 +130,7 @@ jobs:
set -e
mkdir -p artifacts/native-darwin-arm64
cp packages/core/node_modules/@opentui/core-darwin-arm64/libopentui.dylib artifacts/native-darwin-arm64/
cp artifacts/native-notices/* artifacts/native-darwin-arm64/
cd artifacts
zip -r native-darwin-arm64.zip native-darwin-arm64/
test -f native-darwin-arm64.zip || (echo "❌ Failed to create darwin-arm64 zip" && exit 1)
Expand All @@ -129,6 +142,7 @@ jobs:
set -e
mkdir -p artifacts/native-linux-x64
cp packages/core/node_modules/@opentui/core-linux-x64/libopentui.so artifacts/native-linux-x64/
cp artifacts/native-notices/* artifacts/native-linux-x64/
cd artifacts
zip -r native-linux-x64.zip native-linux-x64/
test -f native-linux-x64.zip || (echo "❌ Failed to create linux-x64 zip" && exit 1)
Expand All @@ -140,6 +154,7 @@ jobs:
set -e
mkdir -p artifacts/native-linux-x64-musl
cp packages/core/node_modules/@opentui/core-linux-x64-musl/libopentui.so artifacts/native-linux-x64-musl/
cp artifacts/native-notices/* artifacts/native-linux-x64-musl/
cd artifacts
zip -r native-linux-x64-musl.zip native-linux-x64-musl/
test -f native-linux-x64-musl.zip || (echo "❌ Failed to create linux-x64-musl zip" && exit 1)
Expand All @@ -151,6 +166,7 @@ jobs:
set -e
mkdir -p artifacts/native-windows-x64
cp packages/core/node_modules/@opentui/core-win32-x64/opentui.dll artifacts/native-windows-x64/
cp artifacts/native-notices/* artifacts/native-windows-x64/
cd artifacts
zip -r native-windows-x64.zip native-windows-x64/
test -f native-windows-x64.zip || (echo "❌ Failed to create windows-x64 zip" && exit 1)
Expand All @@ -162,6 +178,7 @@ jobs:
set -e
mkdir -p artifacts/native-linux-arm64
cp packages/core/node_modules/@opentui/core-linux-arm64/libopentui.so artifacts/native-linux-arm64/
cp artifacts/native-notices/* artifacts/native-linux-arm64/
cd artifacts
zip -r native-linux-arm64.zip native-linux-arm64/
test -f native-linux-arm64.zip || (echo "❌ Failed to create linux-arm64 zip" && exit 1)
Expand All @@ -173,6 +190,7 @@ jobs:
set -e
mkdir -p artifacts/native-linux-arm64-musl
cp packages/core/node_modules/@opentui/core-linux-arm64-musl/libopentui.so artifacts/native-linux-arm64-musl/
cp artifacts/native-notices/* artifacts/native-linux-arm64-musl/
cd artifacts
zip -r native-linux-arm64-musl.zip native-linux-arm64-musl/
test -f native-linux-arm64-musl.zip || (echo "❌ Failed to create linux-arm64-musl zip" && exit 1)
Expand All @@ -184,6 +202,7 @@ jobs:
set -e
mkdir -p artifacts/native-windows-arm64
cp packages/core/node_modules/@opentui/core-win32-arm64/opentui.dll artifacts/native-windows-arm64/
cp artifacts/native-notices/* artifacts/native-windows-arm64/
cd artifacts
zip -r native-windows-arm64.zip native-windows-arm64/
test -f native-windows-arm64.zip || (echo "❌ Failed to create windows-arm64 zip" && exit 1)
Expand Down Expand Up @@ -273,6 +292,13 @@ jobs:
test -f artifacts/native-windows-x64.zip || (echo "❌ native-windows-x64.zip missing!" && exit 1)
test -f artifacts/native-windows-arm64.zip || (echo "❌ native-windows-arm64.zip missing!" && exit 1)
test -f artifacts/npm-packages.zip || (echo "❌ npm-packages.zip missing!" && exit 1)
for directory in artifacts/native-{darwin-x64,darwin-arm64,linux-x64,linux-arm64,linux-x64-musl,linux-arm64-musl,windows-x64,windows-arm64}; do
test -f "$directory/LICENSE-LIBWEBP" || (echo "❌ libwebp notice missing from $directory" && exit 1)
test -f "$directory/PATENTS-LIBWEBP" || (echo "❌ libwebp patents missing from $directory" && exit 1)
test -f "$directory/AUTHORS-LIBWEBP" || (echo "❌ libwebp authors missing from $directory" && exit 1)
test -f "$directory/LICENSE-STB" || (echo "❌ stb notice missing from $directory" && exit 1)
test -f "$directory/LICENSE-WUFFS" || (echo "❌ Wuffs notice missing from $directory" && exit 1)
done

echo ""
echo "✅ All 8 native artifacts verified. Ready to upload:"
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"build:lib": "bun scripts/build.ts --lib",
"build:native": "bun scripts/build.ts --native",
"build:native:dev": "bun scripts/build.ts --native --dev",
"vendor:update:images": "sh src/zig/vendor/update.sh",
"test:native": "cd src/zig && zig build test --summary all",
"bench:native": "cd src/zig && zig build bench -Dbench-optimize=ReleaseFast --",
"bench:layout": "bun src/benchmark/layout-benchmark.ts",
Expand Down
10 changes: 10 additions & 0 deletions packages/core/scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,16 @@ export default module.default
)

if (existsSync(licensePath)) copyFileSync(licensePath, join(nativeDir, "LICENSE"))
for (const [source, destination] of [
[join(rootDir, "src", "zig", "vendor", "wuffs", "LICENSE"), "LICENSE-WUFFS"],
[join(rootDir, "src", "zig", "vendor", "stb", "LICENSE"), "LICENSE-STB"],
[join(rootDir, "src", "zig", "vendor", "libwebp", "COPYING"), "LICENSE-LIBWEBP"],
[join(rootDir, "src", "zig", "vendor", "libwebp", "PATENTS"), "PATENTS-LIBWEBP"],
[join(rootDir, "src", "zig", "vendor", "libwebp", "AUTHORS"), "AUTHORS-LIBWEBP"],
] as const) {
if (!existsSync(source)) throw new Error(`Required native image license file is missing: ${source}`)
copyFileSync(source, join(nativeDir, destination))
}
console.log("Built:", nativeName)
}
}
Expand Down
45 changes: 45 additions & 0 deletions packages/core/scripts/dist-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ function writeConsumerPackage(consumerDir: string, coreTarball: string, nativeTa
[packageJson.name]: coreDependency,
[nativePackageName]: nativeDependency,
},
overrides: {
[nativePackageName]: nativeDependency,
},
},
null,
2,
Expand Down Expand Up @@ -236,6 +239,11 @@ assert.equal(typeof core.AudioCaptureStreamError, "function")
assert.equal(typeof core.AudioRecorder, "function")
assert.equal(typeof core.AudioRecorderError, "function")
assert.equal(typeof core.AudioStreamError, "function")
assert.equal(typeof core.NativeImage, "function")
assert.equal(typeof core.ImageRenderable, "function")
assert.equal(typeof core.createHostClipboard, "function")
assert.equal(typeof core.createClipboard, "function")
assert.equal(typeof core.createRendererClipboardAdapter, "function")
assert.equal(typeof core.Audio.prototype.openCapture, "function")
assert.equal(typeof core.Audio.prototype.recordToFile, "function")
assert.equal(typeof core.createIcyStreamDemuxer, "function")
Expand Down Expand Up @@ -263,6 +271,22 @@ const buffer = core.OptimizedBuffer.create(2, 1, "unicode")
assert.equal(buffer.width, 2)
buffer.destroy()

const image = core.NativeImage.fromRgba(Uint8Array.of(1, 2, 3, 255), 1, 1)
const raw = image.takeRaw()
try {
assert.deepEqual([...raw.data], [1, 2, 3, 255])
assert.throws(() => image.info(), /disposed/)
} finally {
raw.dispose()
}

const clipboard = core.createHostClipboard({ timeoutMs: 0 })
try {
assert.equal((await clipboard.read({ preferredTypes: ["text/plain"] })).status, "timed-out")
} finally {
await clipboard.dispose()
}

const dataPath = mkdtempSync(join(tmpdir(), "opentui-node-dist-tree-sitter-"))
const client = new core.TreeSitterClient({ dataPath })
try {
Expand Down Expand Up @@ -341,6 +365,11 @@ describe("${packageJson.name} dist smoke test", () => {
expect(typeof core.AudioRecorder).toBe("function")
expect(typeof core.AudioRecorderError).toBe("function")
expect(typeof core.AudioStreamError).toBe("function")
expect(typeof core.NativeImage).toBe("function")
expect(typeof core.ImageRenderable).toBe("function")
expect(typeof core.createHostClipboard).toBe("function")
expect(typeof core.createClipboard).toBe("function")
expect(typeof core.createRendererClipboardAdapter).toBe("function")
expect(typeof core.Audio.prototype.openCapture).toBe("function")
expect(typeof core.Audio.prototype.recordToFile).toBe("function")
expect(core.NativeAudioStreamCloseReason.TransportError).toBe(1)
Expand All @@ -351,6 +380,22 @@ describe("${packageJson.name} dist smoke test", () => {
expect(typeof parserWorker).toBe("object")
expect(typeof runtimePlugin.createRuntimePlugin).toBe("function")
expect(typeof nativePackage.default).toBe("string")

const image = core.NativeImage.fromRgba(Uint8Array.of(1, 2, 3, 255), 1, 1)
const raw = image.takeRaw()
try {
expect([...raw.data]).toEqual([1, 2, 3, 255])
expect(() => image.info()).toThrow(/disposed/)
} finally {
raw.dispose()
}

const clipboard = core.createHostClipboard({ timeoutMs: 0 })
try {
expect((await clipboard.read({ preferredTypes: ["text/plain"] })).status).toBe("timed-out")
} finally {
await clipboard.dispose()
}
})
})
`,
Expand Down
11 changes: 11 additions & 0 deletions packages/core/scripts/test-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const treeSitterMarkdownRenderableTestDataPath = resolve(tmpdir(), "tree-sitter-
const textBufferTestDataPath = resolve(tmpdir(), "text-buffer-node-test")
const runtimeAssetTestDataPath = resolve(tmpdir(), "opentui-runtime-asset-node-test")
const audioRecorderTestDataPath = resolve(tmpdir(), "opentui-audio-recorder-node-test")
const imageTestDataPath = resolve(tmpdir(), "opentui-image-node-test")
const treeSitterClientTestDataPaths = [
"tree-sitter-shared-test-data",
"tree-sitter-injections-test-data",
Expand All @@ -32,10 +33,12 @@ const treeSitterTestDataPaths = [
textBufferTestDataPath,
runtimeAssetTestDataPath,
audioRecorderTestDataPath,
imageTestDataPath,
...treeSitterClientTestDataPaths,
]
const treeSitterAssetsDir = "src/lib/tree-sitter/assets"
const audioFixturesDir = "src/tests/fixtures/audio"
const imageFixturesDir = "src/tests/fixtures/images"
const nodeTestTimeoutMs = 30_000
const nodeProcessTimeoutMs = 10 * 60_000
const nodePath = requireNode26()
Expand All @@ -46,6 +49,9 @@ const emittedAllowlist = [
".node-test/src/lib/bunfs.test.js",
".node-test/src/lib/border.test.js",
".node-test/src/lib/clipboard.test.js",
".node-test/src/lib/clipboard-service.test.js",
".node-test/src/lib/host-clipboard.test.js",
".node-test/src/lib/host-clipboard.native.scheduler.test.js",
".node-test/src/lib/extmarks.test.js",
".node-test/src/lib/detect-links.test.js",
".node-test/src/lib/extmarks-multiwidth.test.js",
Expand Down Expand Up @@ -126,7 +132,10 @@ const emittedAllowlist = [
".node-test/src/tests/renderable.snapshot.test.js",
".node-test/src/tests/allocator-stats.test.js",
".node-test/src/tests/audio-stream.test.js",
".node-test/src/tests/clipboard-native-lifecycle.test.js",
".node-test/src/tests/audio.test.js",
".node-test/src/tests/image-renderable.test.js",
".node-test/src/tests/image.test.js",
".node-test/src/tests/destroy-on-exit.test.js",
".node-test/src/tests/destroy-during-render.test.js",
".node-test/src/tests/ffi-borrowed-pointer-callsites.test.js",
Expand Down Expand Up @@ -195,6 +204,7 @@ try {
if (exitCode === 0) {
cpSync(resolve(packageRoot, treeSitterAssetsDir), resolve(outDir, treeSitterAssetsDir), { recursive: true })
cpSync(resolve(packageRoot, audioFixturesDir), resolve(outDir, audioFixturesDir), { recursive: true })
cpSync(resolve(packageRoot, imageFixturesDir), resolve(outDir, imageFixturesDir), { recursive: true })
for (const dataPath of treeSitterTestDataPaths) {
mkdirSync(dataPath, { recursive: true })
}
Expand Down Expand Up @@ -226,6 +236,7 @@ try {
OTUI_TEXT_BUFFER_TEST_TMPDIR: textBufferTestDataPath,
OTUI_RUNTIME_ASSET_TEST_TMPDIR: runtimeAssetTestDataPath,
OTUI_AUDIO_RECORDER_TEST_TMPDIR: audioRecorderTestDataPath,
OTUI_IMAGE_TEST_TMPDIR: imageTestDataPath,
XDG_DATA_HOME: treeSitterDefaultDataPath,
},
timeout: nodeProcessTimeoutMs,
Expand Down
Loading
Loading