- Create logger factory with explicit module names (no stack traces)
- Support log/warn/error/debug levels with clean method names
- Write to ~/.vibetunnel/log.txt with automatic cleanup on startup
- Add colored console output with timestamps and module names
- Support debug mode via flag or environment variable
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Applications like Claude CLI use ANSI escape sequences to hide the cursor
(\x1b[?25l) and render their own cursor with inverse text. The terminal
component now tracks cursor visibility by parsing these sequences in the
write() method and respects the visibility state when rendering.
- Added cursorVisible state that defaults to true
- Parse \x1b[?25l (hide) and \x1b[?25h (show) sequences in write()
- Only render cursor when both on cursor line AND cursor is visible
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The direct notification system wasn't being used since hasListeners()
was checking before any listeners were set up. All sessions were using
file watching anyway. Simplified the code by removing the unused
notification system and keeping only the optimized file watching.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
AsciinemaWriter always writes a header, so we can trust it exists.
Removed all the default header construction logic and headerSent tracking.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Integrate stat checking directly into StreamWatcher
- Remove platform-specific code paths that all used fs.watch anyway
- Keep the actual optimization: checking file stats to avoid spurious events
- Simpler, cleaner code with the same benefits
The real improvements remain:
1. Direct notifications for in-process sessions
2. Stat checking to verify actual file changes
3. Only processing when file size increases
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Check upfront if we have listeners for direct notifications
- Use EITHER direct notifications OR file watcher, not both
- This eliminates any possibility of duplicate broadcasts
- Server sessions get instant updates via direct notifications
- Forwarded sessions use optimized file watcher
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Only use file watcher if no direct notifications are available
- Remove unnecessary deduplication logic
- Clean up logging for direct notifications
- Wait 100ms to detect if we're getting direct notifications before
starting file watcher (for cross-process scenarios)
This should eliminate duplicate broadcasts and improve latency for
server-created sessions while maintaining compatibility with fwd.ts
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The issue was that sendInput() was processing input twice:
1. Writing directly to PTY + asciinema for in-memory sessions
2. Then continuing to socket path which would write again
Added early return after in-memory session processing to avoid
the socket path when we already have a direct PTY reference.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add deduplication logic to prevent the same line from being broadcast
twice when both direct notification and file watcher fire. Uses a
simple hash and 50ms time window to detect duplicates.
This fixes the double input issue in server-created sessions.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add platform-specific optimized file watcher
- Linux: inotify with rapid polling after changes
- macOS: FSEvents + periodic checks to overcome batching
- Windows: ReadDirectoryChangesW with debouncing
- Add direct in-process notifications via StreamNotifier
- Bypasses file watching for same-process sessions
- Near-instant latency for server-created sessions
- Update StreamWatcher to use both mechanisms
- Primary: Direct notifications (microsecond latency)
- Fallback: Optimized file watching (for fwd.ts)
- Add latency and stress test scripts
This should significantly reduce streaming latency, especially
for sessions created by the server process.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add synchronous wait in applicationWillTerminate to ensure server stops before app exits
- Implement parent process monitoring in server spawn script
- Server now monitors parent PID and self-terminates if parent dies
- Handles both graceful shutdown and force-quit scenarios
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Display version number inline with session started message
- Show build date and git commit in session info
- Import version details from version.ts
🤖 Generated with Claude Code (https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix iOS CI to use correct workspace and scheme names
- Update iOS test script to use workspace instead of project
- Fix all TypeScript 'any' type warnings by adding proper types
- Update build destination format for Xcode 16 compatibility
- Add fs.fsyncSync after each asciinema event write to trigger file watchers immediately
- Keep socket connections alive with setKeepAlive for better performance
- Add response flushing in SSE streams to prevent buffering
- Fix the ~100ms input lag that was affecting forwarded sessions vs server-created sessions
The lag was caused by buffered writes not immediately triggering file system watchers.
Forwarded sessions now feel as responsive as server-created sessions.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>