Set UTF-8 locale in all PTY spawn environments, add xterm-addon-unicode11
for proper double-width character measurement, and update LocalEchoOverlay
helpers to respect CJK character visual width in positioning, line wrapping,
and cursor placement.
Based on PR #13 by @TeigenZhang, adapted to current codebase structure.
Co-Authored-By: Tenggan Zhang <TeigenZhang@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The "Startup Mode" setting (normal/bypass/allowedTools) was saved to
settings but never read when spawning sessions. All code paths had
--dangerously-skip-permissions hardcoded. Now reads claudeMode from
~/.claudeman/settings.json and passes it through Session → TmuxManager.
Closes#12
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Mobile-Optimized Web UI section used align="left" on a 280px image,
leaving only ~110px for text on 390px mobile screens. This caused
single-character-per-line text wrapping on GitHub mobile view. Changed
to stacked layout: text description above, centered image, then
comparison table below.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix repository URL: nicobailon/claudeman → Ark0N/Claudeman
- Rewrite xterm-zerolag-input README with badges, origin story, architecture
diagrams, better API docs, integration patterns, and "Why This Is Hard"
- Add Published Packages section to Claudeman README with quick start example
- Add callout in Claudeman's local echo section linking to the npm package
- Publish as xterm-zerolag-input@0.1.2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pitfall 3 (REAL BUG): setFlushed() called _render() unconditionally.
During tab switch, rendering against a stale buffer found the old
session's prompt and locked the column position via the flushed-text
column lock. After the new buffer loaded, rerender() kept the stale
column. Fix: add render parameter (default true), pass false during
tab-switch restore to defer rendering until buffer is loaded.
Pitfall 2: Tab completion "undo" required calling clearFlushed() +
resetBufferDetection() separately — easy to get wrong. Add
undoDetection() convenience method that atomically clears flushed
state and re-enables detection.
Pitfall 1: Backspace Map sync is app-specific (can't be fixed in lib),
but removeChar() return value + getFlushed() make the pattern clean.
Updated tab-switch test to demonstrate the correct pattern.
Tests: 78 total (+4 new)
- setFlushed render=false prevents stale column lock
- setFlushed render=false keeps overlay hidden
- undoDetection clears flushed + re-enables detection
- undoDetection preserves pending text
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Second deep audit comparing all 43 integration points in Claudeman's
app.js against the library API found one critical gap:
- Add suppressBufferDetection() — needed when switching to sessions
with UI framework text (Ink) after the prompt that would be falsely
detected. Claudeman sets _bufferDetectDone=true externally; this
method provides the public equivalent.
Tests: 74 total (+13 new)
- Tab-switch save/restore pattern (flushed state roundtrip)
- suppressBufferDetection blocks explicit, implicit (addChar), and
cascade (removeChar) detection paths
- clear() resets suppression
- Methods safe before activate() and after dispose()
- addChar implicit buffer detection on first keystroke
- refreshFont with flushed-only text
README: rewritten from 207 to 459 lines with:
- removeChar cascade explanation with return value table
- Flushed text concept explained
- Integration patterns: buffered, char-at-a-time, tab switching,
tab completion, Ink/TUI frameworks, SSE reconnect, resize, font
- Architecture diagram (keypress → DOM overlay → PTY echo flow)
- Prompt column locking, text wrapping, render cache, scroll awareness
- All known limitations documented
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Regex global flag safety — strip `g` flag before matching to prevent
lastIndex mutation and missing .index on match results
2. state.visible false before activate — null overlay no longer reports
visible: true
3. removeChar() returns 'pending' | 'flushed' | false instead of boolean
so consumers can distinguish whether to send backspace to PTY
4. removeChar() implements buffer detection cascade (step 3) — detects
existing prompt text when both pending and flushed are empty
5. RenderKey includes text content, not just length — prevents stale
renders when setFlushed() called with same count but different text
6. Remove dead `import type { Terminal }` from test file
7. Remove internal `FontStyle` from public exports
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract Claudeman's local echo overlay into a reusable xterm.js addon
at packages/xterm-zerolag-input/. Provides instant keystroke feedback
via a DOM overlay, eliminating perceived input latency over high-RTT
connections (SSH, mobile, cloud IDEs).
- Zero dependencies, compatible with xterm v5.x and @xterm/xterm v5.4+
- Configurable prompt detection (character, regex, or custom function)
- Flushed text tracking for tab-switch / deferred echo scenarios
- Per-character grid-aligned rendering matching xterm's canvas output
- 56 tests passing (prompt finder, overlay renderer, full addon lifecycle)
- Dual CJS/ESM build with full TypeScript declarations
Claudeman source is unchanged — migration to consume this lib is a
separate follow-up.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>