Re-audit of main (all 16 sweep-1 fixes merged) vs Ink 40b3a75 found 8 confirmed divergences the first sweep missed: - G18 (HIGH): no signal-based teardown — terminal corrupted on SIGINT/SIGTERM/SIGHUP. - G19 (med): dynamic yoga prop removal doesn't reset to default (stale layout). - G20: writeToStdout/stderr lack an isUnmounted guard. - G21: nested <Transform> in <Text> gets hardcoded index 0 (squash path; refines the earlier G06 refutation — the inline/nested case IS a gap). - G22: SR role dedup inherits grandparent role. - G23: <Transform> under <Box> SR-joins children with newline (should concatenate). - G24 (CANDIDATE): vue-tui supports multiple <Static>; Ink has one staticNode — awaiting maintainer decision (appended to ink-parity.md candidates, like G07). Also reconciles G17 -> merged (#45). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
4.7 KiB
Ink Parity — Reference Pin & Intentional-Divergence Allowlist
The audit in ink-parity-loop diffs vue-tui against the Ink source pinned below. Anything listed under "Intentional divergences" is deliberate and is NOT a gap — the audit skips it. Confirmed gaps and sweep history live in parity-ledger.
Target Ink reference
| field | value |
|---|---|
| package | ink (vadimdemedes/ink) |
| version | v7.0.4 |
| tag | v7.0.4 |
| pinned commit SHA | 40b3a7578811fd616341ca4e31cc7748aeeff12f |
| clone | git clone --depth 1 --branch v7.0.4 https://github.com/vadimdemedes/ink.git /tmp/ink-40b3a75 |
| verify | git -C /tmp/ink-40b3a75 rev-parse HEAD must equal the pinned commit SHA above |
Note:
git ls-remote …/ink refs/tags/v7.0.4returnsc4f638cf…, the annotated tag object SHA — not the commit. The commit the tag points to is40b3a75…(what we pin and whatrev-parse HEADresolves to after checkout). Pin the commit, not the tag object.
Re-pin deliberately when bumping the target Ink version: update the row above, note the bump in the ledger sweep history, and re-run a full audit against the new SHA.
Intentional divergences (allowlist — skip these)
These are differences the audit must treat as by design. Format:
area — what Ink does — what vue-tui does — why.
- Entry API — Ink exposes
render(); vue-tui exposescreateApp(). Renamed to match Vue'screateAppmental model. Deliberate. - Text measurement exports — Ink does not export its
measure-textmodule; vue-tui exportsmeasureText/measureTextNaturalfrom the public index. Deliberate public surface. - App composable — Ink's
useApp()returns the full AppContext (exit +waitUntilRenderFlush+ stdout/stdin/…); vue-tui exposesuseExit()returning only the exit fn. Intentional minimal surface. (waitUntilRenderFlushis not exposed as a composable.) - Accessibility props — vue-tui adds
AriaRole/AriaStateprops with no Ink equivalent. Additive, deliberate. - Named type/prop re-exports — Ink re-exports BoxProps, TextProps, StaticProps, TransformProps, NewlineProps, WindowSize, CursorPosition, DOMElement, RenderOptions, Instance, App/Stdin/Stdout/StderrProps. vue-tui intentionally does not re-export these names (uses TuiApp / MountOptions and its own type surface instead).
- React concurrent mode — Suspense / useTransition have no Vue equivalent. N/A, not a gap.
Candidate intentional divergences (needs human review)
(The loop appends here when it finds a difference it suspects is intentional but that is not yet on the allowlist. A human promotes entries up into the allowlist — the loop never does.)
- Kitty-protocol Ctrl+C exits the app (G07) — Ink does NOT exit on a kitty-encoded
Ctrl+C (
\x1b[99;5u):use-input.ts:245-247onlyreturns (suppresses the user handler), and Ink's real exit path (App.tsx:244-246) fires only on the literal\x03byte, which kitty never produces. vue-tui'suseInput.ts:100-105callsapp.exit()directly oninput==='c' && key.ctrl, so Ctrl+C exits under BOTH legacy and kitty protocols. This is arguably better UX than Ink (Ctrl+C reliably exits) and looks like a kitty-era oversight in Ink rather than a deliberate choice. Flagged for the maintainer to decide: keep vue-tui's behavior (promote to the allowlist) or match Ink (remove the kitty-path exit so only\x03exits). Not auto-changed — removing a working Ctrl+C-exits behavior to match an Ink limitation needs a human call. Tracked as G07 in parity-ledger (statuscandidate). - Multiple
<Static>nodes supported (G24) — vue-tui'sfindStatics(root)collects and renders EVERY<Static>in the tree; Ink maintains a singlestaticNode(only the most-recent<Static>renders). So vue-tui supports multiple<Static>regions, which Ink does not — matching Ink would REMOVE that capability. Flagged for the maintainer: keep vue-tui's multi-Static support (promote to allowlist) or restrict to Ink's single staticNode. Not auto-changed. Tracked as G24 in parity-ledger (statuscandidate).