#### Brief overview of PR changes/additions
- line wrapping now always moves on: a width too narrow for a single
glyph used to break the line at the character the scan was already on,
looping forever on the main thread
- `setWindowWrap()` refuses widths below 1 (the range Preferences
offers) and answers `true` when it accepts one; Geyser's `setWrap()`
passes a refusal on and its autoWrap never derives 0 columns
- new `NarrowWindowWrapTest` (9 cases, 5 of them verified to hang
without the fix) plus busted coverage of the Lua and Geyser contracts
#### Motivation for adding to Mudlet
`setWindowWrap(0)` froze Mudlet completely as soon as the next line was
displayed, and so did an ordinary wrap width of 1 with East Asian text,
or an indent that used the width up.
#### Other info (issues closed, discussion etc)
Fixes#9622
**Test case:** `lua setWindowWrap(0)` then `lua getWindowWrap()` -
Mudlet used to freeze; now the first call reports "wrapAt must be
greater than zero" and the client keeps running.
Assisted-by: Claude:claude-opus-5