@manypkg/get-packages only includes workspace members in its packages list,
not the workspace root. Adding "." to workspaces makes the root package
discoverable, fixing "not in the workspace" errors from changeset version.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause: toggleTunnelFromWelcome() sent the entire settings object
back to PUT /api/settings, but the Zod schema uses .strict() which
rejects unknown fields (lastUsedCase, localEchoEnabled, etc.). The PUT
silently failed, so the tunnel never started.
Fix: send only {tunnelEnabled: true/false} instead of the full blob.
Also added polling fallback for tunnel status and server-side re-broadcast
when tunnel is already running.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Re-broadcast tunnel:started SSE event when tunnel is already active
and user toggles the setting, so the client receives the URL.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both are local state files. plan.json was already gitignored,
skills-lock.json now added to .gitignore.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove remotion-best-practices skill files from tracking.
Local files preserved, just hidden from the repo.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add _isStopped guard to OpenCode 3s readiness timeout (session.ts)
- Block respawn for opencode sessions on interactive-respawn and
respawn/enable routes (server.ts)
- Fail fast in direct PTY fallback for OpenCode mode (session.ts)
- Validate configContent as JSON at schema level (schemas.ts)
- Update JSDoc example for createSession options API (tmux-manager.ts)
- Un-hide Context tab for OpenCode sessions (index.html)
- Add OpenCode UI tests (opencode-resize.test.ts)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When running the dev server inside a tmux session, $TMUX is inherited
and tmux refuses to create new sessions ("sessions should be nested
with care, unset $TMUX to force"). Production (systemd) has a clean
env so this only affects dev/test. Strip $TMUX from the execSync env
when calling tmux new-session.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace dead .btn-claude selectors in mobile.css with proper styling
for the new split run button (.btn-run + .btn-run-gear). Add mobile
touch-friendly dropdown menu options (10px padding, 35px height).
Include mode-specific colors for both Claude (blue) and OpenCode
(green) on mobile. Also guard Claude-specific features (Ralph,
Respawn) from running on OpenCode sessions in server.ts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After the 3s TUI stabilization timeout, emit needsRefresh so the
client fetches the full terminal buffer. Without this, the terminal
appears empty until the user manually refreshes or switches tabs.
Wire needsRefresh as a proper session listener in server.ts with
cleanup in both removal paths to prevent memory leaks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace separate "Run Claude" and "Run OC" buttons with a single
split button: [Run ▾] where the chevron opens a dropdown to switch
between Claude Code and OpenCode modes.
- Run button label shows "Run" (Claude) or "Run OC" (OpenCode)
- Button color reflects selected mode (blue=Claude, green=OpenCode)
- Mode persisted in localStorage across sessions
- Ctrl+Enter uses the selected mode
- Welcome screen simplified to single "Run" button
- Removed standalone btn-claude, btn-opencode, welcome-btn-opencode CSS
- Updated welcome tagline: "Manage AI in persistent tmux sessions"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use a cursor-based prompt finder for OpenCode's Bubble Tea TUI:
- Custom finder locates ┃ (U+2503) border on the cursor's row
- Offset 3 skips "┃ " to reach the text input start position
- Prompt finder is swapped dynamically when switching between
Claude (❯ character) and OpenCode (┃ border) sessions
- Added setPrompt() method to ZerolagInputAddon for runtime updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The local echo overlay buffers keystrokes locally and renders them
in a DOM overlay anchored to the '>' prompt character. OpenCode's
Bubble Tea TUI uses a different prompt (┃), so the overlay can't
find it — keystrokes buffer invisibly and nothing appears on screen.
Disable local echo for OpenCode sessions so keystrokes flow directly
to the PTY via the normal input path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>