216a7021a0
* fix(runtime): restore terminal on signal exit via signal-exit (Ink parity, G18)
Previously nothing routed a process signal to teardown(): SIGINT-as-signal,
SIGTERM or SIGHUP killed the process with the cursor hidden, the alternate
screen active and raw mode on, leaving the terminal corrupted.
Mirror Ink (ink.tsx:426): register signal-exit's onExit(teardown,
{alwaysLast:false}) at interactive mount, storing the unsubscribe fn, and
call it first thing in teardown() (ink.tsx:765) so the handler is removed on
unmount()/exit() and can't leak or double-run. teardown() stays idempotent
(teardownStarted guard) so a signal-triggered teardown plus a later unmount
won't double-run, and we don't prevent the process from exiting. Only the
live interactive, non-debug mount registers — render-to-string /
non-interactive paths never touch process signal handlers; registration is
guarded against double-registration.
Uses signal-exit v4 (named onExit export; ships ESM + types, so no
@types/signal-exit needed). PTY test sends SIGINT/SIGTERM/SIGHUP to a mounted
alt-screen app and asserts the captured output ends with show-cursor
(\x1b[?25h) + leave-alt-screen (\x1b[?1049l).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review follow-ups (3 fixes): register signal-exit whenever interactive
(drop the !debug gate so debug-but-interactive apps, which still enter the
alt-screen/hide the cursor, restore on signal — Ink ink.tsx:426); add
!teardownStarted to the registration so a spent app instance does not
re-register on a same-instance remount (the next unmount() returns early at
the teardownStarted guard before it could unsubscribe — a leak); and make
the PTY test prove the SIGNAL drove teardown (fixture never self-unmounts, so
restore bytes can only come from the signal path) with a debug-mode signal
test, an exit-anchored waitForOutput drain, and a bounded retry for the
async-flush race under saturated runners.
Review follow-ups (2 fixes): synchronous restore flush on signal — the
signal-exit teardown path now writes the restore escapes (show-cursor,
leave-alt-screen, disable-kitty) via fs.writeSync to the stdout fd so they
reach the terminal before signal-exit re-raises the signal (a buffered async
stream.write could be lost on abrupt exit); the normal unmount path keeps async
writes. Removed the config-wide retry:3 from vitest.pty.config.ts (it masked
the whole PTY suite) and scoped a retry:2 to the signal-teardown describe only,
for the residual parent-side node-pty onData read-race under a saturated runner.
* chore(parity): ledger — G18 pr-open
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
55 lines
1.3 KiB
JSON
55 lines
1.3 KiB
JSON
{
|
|
"name": "@vue-tui/runtime",
|
|
"version": "0.0.2",
|
|
"description": "Vue 3 terminal renderer with Yoga flexbox layout, inspired by React Ink.",
|
|
"license": "MIT",
|
|
"files": [
|
|
"dist"
|
|
],
|
|
"type": "module",
|
|
"exports": {
|
|
".": "./dist/index.mjs",
|
|
"./internal": "./dist/internal.mjs",
|
|
"./package.json": "./package.json"
|
|
},
|
|
"publishConfig": {
|
|
"access": "public"
|
|
},
|
|
"scripts": {
|
|
"build": "vp pack",
|
|
"dev": "vp pack --watch",
|
|
"test": "vp test",
|
|
"check:type": "tsc --noEmit",
|
|
"prepublishOnly": "vp run build"
|
|
},
|
|
"dependencies": {
|
|
"@alcalzone/ansi-tokenize": "catalog:",
|
|
"@vue/runtime-core": "^3.4.0",
|
|
"ansi-escapes": "catalog:",
|
|
"chalk": "^5.3.0",
|
|
"cli-boxes": "^3.0.0",
|
|
"cli-truncate": "^6.0.0",
|
|
"is-in-ci": "catalog:",
|
|
"patch-console": "catalog:",
|
|
"signal-exit": "^4.1.0",
|
|
"slice-ansi": "^9.0.0",
|
|
"string-width": "^8.0.0",
|
|
"terminal-size": "catalog:",
|
|
"wrap-ansi": "^10.0.0",
|
|
"yoga-layout": "^3.1.0"
|
|
},
|
|
"devDependencies": {
|
|
"@types/node": "^25.6.2",
|
|
"@vitejs/plugin-vue-jsx": "catalog:",
|
|
"typescript": "^6.0.3",
|
|
"vite-plus": "^0.1.20",
|
|
"vue": "^3.4.0"
|
|
},
|
|
"peerDependencies": {
|
|
"vue": "^3.4.0"
|
|
},
|
|
"engines": {
|
|
"node": ">=22"
|
|
}
|
|
}
|