Files
Codeman/packages/xterm-zerolag-input/CHANGELOG.md
T
Codeman maintainer 23f258a85d chore: version packages
Release 1.9.8 (aicodeman) and 0.1.8 (xterm-zerolag-input).

Fixes macOS session start (`posix_spawnp failed.`, issues #6 and #204):
node-pty ships its macOS spawn-helper as mode 0644 and macOS launches every
PTY through it. `scripts/fix-node-pty.mjs` (npm run fix:node-pty) chmods every
helper, prebuilds/ included, then verifies by really opening a PTY; the blind
Node-22+ rebuild is gone. `spawnPtyWithHelperRepair()` self-heals an already
broken install on the first failed spawn.

Adds the phone home screen (session overview under 430px, per-device
`mobileOverviewEnabled`, default ON) and a guided Tailscale path in
install.sh, plus `install.sh tailscale` to retrofit it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 15:02:46 +02:00

9.1 KiB

xterm-zerolag-input

0.1.8

Patch Changes

  • Fixed: sessions failed to start on macOS with Error: posix_spawnp failed. (issues #6 and #204)

    node-pty@1.1.0 publishes its macOS prebuilt helper as prebuilds/darwin-<arch>/spawn-helper with mode 0644, i.e. no execute bit. macOS launches every PTY through that helper, so a stock install failed on every session start. The bug is macOS-only: spawn-helper is a mac-only gyp target and node-pty ships no Linux prebuild, so Linux always compiles a correctly-permissioned helper from source.

    The previous fix chmodded only build/Release/spawn-helper, which on macOS does not exist (the prebuild is used, so node-gyp never runs), and it derived that path from require.resolve('node-pty'), landing on <pkg>/lib/build/Release/.... It was a no-op on every platform.

    • New scripts/fix-node-pty.mjs (also npm run fix:node-pty) chmods every spawn-helper it finds, in build/Release, build/Debug and each prebuilds/*/, then verifies the result by actually opening a PTY. A require() alone passes on a broken install, because the helper is only touched at spawn time.
    • postinstall no longer force-rebuilds node-pty from source on Node 22+. That step needed Xcode command line tools, cost 30-120s on every install, and deleted the prebuilds/ tree before compiling, so a Mac without a compiler was left with no working binary at all. A rebuild now happens only when the chmod plus spawn probe still fails, and the prebuilds tree is backed up and restored around it.
    • New spawnPtyWithHelperRepair() (src/utils/node-pty-repair.ts) wraps every pty.spawn() in session.ts, so an install that is already broken repairs itself on the first failed spawn and retries in-process instead of showing a dead session. Unrelated spawn errors are rethrown untouched; a second failure carries the npm run fix:node-pty hint.
    • scripts/fix-node-pty.mjs is now in the published files list, so global npm installs get the repair too.
    • Direct-PTY Claude spawns use the resolved absolute binary path (new getClaudeBinaryPath()) instead of the bare name claude, so a CLI installed outside the server's PATH still launches.

    Verified end to end on macOS 26.4 arm64: a stock npm i reproduces posix_spawnp failed., and after the fix the same install spawns a PTY successfully with the prebuilds preserved.

    Added: phone home screen (session overview)

    Under 430px the "C" logo now opens a session overview (current sessions, past sessions, spaces) instead of the welcome overlay: on a small screen "which session needs me" beats "how do I start one". Rows resume a session in place, and "New session here" goes through the normal quick-start path so remote and Docker cases keep their routing. Per-device setting mobileOverviewEnabled (phones only, default ON) in App Settings. Tablet and desktop are unchanged.

    Added: guided Tailscale setup in install.sh

    The network-access prompt is now 3-way: Tailscale, LAN, or local-only. The Tailscale path binds loopback and walks through installing Tailscale, logging in, the operator grant, the tailnet HTTPS-certificates toggle, and tailscale serve --bg <port>, then verifies the result end to end with curl. That gives HTTPS on a real certificate with no app password and no 0.0.0.0 bind, which is also what PWA install and web push need. install.sh tailscale retrofits it onto an existing install, and CODEMAN_TAILSCALE=1 presets the choice. Serve state is detected from tailscale serve status --json; the installer never runs tailscale serve reset and never touches serve mappings other than 443 to Codeman's port. README and docs/security-architecture.md updated to match.

    Docs: replaced a real tailnet hostname with placeholders in docs/web-tabs-fixes-plan.md.

    xterm-zerolag-input: npm description and keywords only, no code change.

0.1.7

Patch Changes

  • Fix a latent bug where a partial settings PUT silently reset live service state, and trim the xterm-zerolag-input README callout.
    • PUT /api/settings no longer resets watchers on a partial body. The three toggleService calls (subagent watcher, workflow-run watcher, image watcher) read the raw request body with ?? defaults, so every key a caller omitted was treated as "apply the default". A body of just {statusLineTelemetry:true} would START the subagent watcher and STOP the workflow and image watchers, undoing the persisted config. They now resolve from merged (persisted settings + incoming), the same convention the tmuxHistoryLimit branch in that handler already used, so any PUT reconciles services to the effective stored state. Nothing triggered this in practice because every shipped client sends a full settings payload rebuilt from the DOM, but it was a trap for the next partial-update caller.
    • Regression test: test/routes/system-routes-settings-partial-put.test.ts (4 cases) pins both directions, omitted keys preserve state and explicit keys still take effect. Verified to fail against the pre-fix handler.
    • CLAUDE.md records the rule under "Adding Features → App setting": anything acting on a setting in that handler must resolve from merged, never the request body.
    • xterm-zerolag-input README: removed the links line (getcodeman.com / install one-liner / star link) from the Codeman callout above the demo GIF. The callout keeps its links in the heading and body.

0.1.6

Patch Changes

  • Plan-usage chip now defaults ON on desktop, plus the reworked xterm-zerolag-input README.
    • Plan-usage chip defaults ON (desktop). The showPlanUsageLimits chip (live 5-hour and weekly plan usage from the Claude statusline) used to be opt-in and default OFF, so most users never saw it. Desktop now defaults ON; handhelds still default OFF so the phone header stays minimal and the mobile-header-buttons-policy guard keeps passing. Devices with an explicitly stored preference keep whatever they chose, so nobody's OFF gets overridden.
    • One resolver behind the chip. Added planUsageChipEnabled() in settings-ui.js and routed all three call sites through it: the App Settings checkbox, the chip's visibility, and the create-time statusLineTelemetry flag in session-ui.js. Those three had independent ?? false / === true defaults, and a chip revealed without the telemetry flag renders — forever, so a default flip on one site alone would have shipped a permanently empty chip.
    • Cron button comment corrected. The App Settings comment claimed "Cron button defaults ON" while the code, the template (btn-cron--hidden) and the CSS all default it OFF. Verified against a fresh browser profile: the button is hidden and its checkbox unchecked out of the box. Comment now matches, and states why the two halves stay consistent.
    • Docs. CLAUDE.md, docs/architecture-invariants.md and docs/usage-limits-display-plan.md updated for the new default and the single-resolver rule; the stale styles.css comment claiming the server strips the chip's hidden class at render was corrected (display is per-device, so the client reveals it).
    • xterm-zerolag-input README rework (0.1.5 shipped the content; this republishes with the graphic and promo changes): replaced the misaligned 8-line keystroke-flow diagram with a two-line stock-vs-zerolag contrast, added a Codeman callout above the demo GIF with links to getcodeman.com and the repo, and rewrote the Origin section so it argues the extraction story instead of repeating the promo.

0.1.5

Patch Changes

  • Rewrite the xterm-zerolag-input package README as a value-first document and correct the drift that had accumulated against the source.

    • Added the side-by-side phone demo GIF (docs/images/zerolag-demo-20260728.gif) as the hero image, referenced by absolute raw URL so it renders on npmjs.com as well as GitHub. The two-phone comparison shows 0ms local echo next to a 600ms-2.7s server echo on the same session.
    • New "Why this one" comparison table, an explicit list of target use cases (SSH web clients, cloud IDEs, mobile terminals, container consoles), and a bundle-size badge (6.1 kB gzipped, measured from the ESM build).
    • Corrected the test-count badge from 78 to the actual 175 tests across 5 files, in both the package README and the Published Packages section of the root README.
    • Removed the stale "Unicode/emoji rendered at single-cell width" limitation. CJK, fullwidth forms and emoji have had double-width rendering and visual-column positioning since the wide-character fix; the honest remaining caveat (per-code-point width summing over-counts ZWJ grapheme clusters) replaces it.
    • Documented the previously undocumented public setPrompt() method for switching prompt strategies at runtime, and the new "Wide characters (CJK, emoji)" integration section covering the optional Unicode11Addon path and the built-in range-table fallback.
    • Documented backgroundColor: 'transparent', corrected the foregroundColor default, and updated the grid-alignment math to reflect visual-column positioning rather than character index.

    No source changes, docs only.

0.1.4

Patch Changes

  • Initial changelog entry for changesets-based versioning