v0.2.1
Correctness patch. Every entry below was found by probing the published
0.2.0 rather than reading the source, and each one is a case where the
harness quietly did the wrong thing, panicked inside a dependency, or —
in the worst of them — hung itself.
Changed
pastenow transforms the text the way a real terminal does, so what
the application receives matches what a user pasting would produce.
Line breaks become\r(the byte Enter sends; applications in raw
mode never see\nfrom a terminal), and while bracketed paste is
active, paste markers embedded in the text are removed — previously an
ESC[201~inside the text ended the paste early and the remainder
arrived as ordinary key presses.send_strremains the untransformed
path.
Fixed
- The harness can no longer deadlock itself. Query replies were
written by the reader thread, so an application that emitted queries
faster than it read the answers filled the PTY's input queue, blocked
that write, and stopped the drain — after which the child blocked
writing and neither side could proceed. Reproduced in the default
configuration with no test input at all: the wait timed out with a
stale screen and thenDropnever returned. Replies now go to a
dedicated responder thread, so the drain never writes; undeliverable
replies are counted and reported ("the application is not reading its
input") instead of stalling anything.Drop's reap is bounded too —
teardown must always terminate. - Mouse reports now follow the UTF-8 encoding (mode 1005) when the
application selects it. The encoding was collapsed to "SGR or not", so
a 1005 application received the legacy form — identical below column
95, and a bare non-UTF-8 byte past it, which such an application
cannot decode. - The unanswered-query diagnosis no longer misattributes unrelated
failures. It was recorded once and never cleared, so a single
deliberately-unanswered probe at startup (kitty'sCSI ? uis the
common one) claimed to be the cause of every later timeout. A query is
now only blamed while the application has produced no output since
asking; otherwise it is reported as context. Every unanswered query is
named rather than just the most recent, the set is bounded, and
wait_frameand theEoferrors carry the note too — previously
wait_framewithheld it, which is the worst place for it to be
missing, since an application blocked on a probe never reaches its
first repaint. wait_frametimeouts embed the live screen, like every other
wait. They previously embedded the last completed frame — which can be
arbitrarily old — under a header saying "screen at timeout", so the
one place a CI log is the only evidence showed the wrong screen. The
count of observed frames is still in the message.- A zero terminal dimension is now a typed
Error::Inputfromspawn
andresizeinstead of a panic inside the emulator. In release builds
— the profile the stress workflow uses — it was worse than a panic:
the arithmetic wrapped, both calls returnedOk, and the emulator
panicked on the reader thread, silently killing the drain so every
later snapshot was blank and a careless test went green. current_dirpointing at a path that is not an existing directory now
fails the spawn instead of being silently ignored: the PTY layer
falls back to the home directory, so a directory-sensitive test could
pass against the wrong tree with no error anywhere.spawn("")now fails with a one-lineError::Spawnnaming the problem
instead of surfacing the PTY layer's entirePATHsearch. Genuine
"program not found" failures keep their underlying diagnosis.