Commit Graph

13 Commits

Author SHA1 Message Date
Vantz Stockwell
c4335e0b4f fix: 6 UX regressions — popups, themes, cursor, selection, status bar
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 4m14s
Cursor blinking (ACTUALLY fixed this time):
- handleFocus() was STILL missing due to botched duplicate removal in
  v1.12.1. Now defined once at line 80, no duplicates.
- vue-tsc --noEmit now runs clean (was erroring with TS2393)

Tool windows:
- App.vue now has onErrorCaptured + error display overlay so tool window
  crashes show the error instead of silently closing
- defineAsyncComponent uses object form with onError callback for logging

Selection highlighting:
- Changed from rgba(88,166,255,0.4) transparent to solid #264f78
  (VS Code's selection color) — always visible on dark backgrounds
- Applied to default theme, TerminalView applyTheme, LocalTerminalView

CSP:
- Simplified to 'self' 'unsafe-inline' asset: for default-src
- Separate connect-src for IPC protocols

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 11:13:54 -04:00
Vantz Stockwell
2838af4ee7 fix: 6 UX regressions — popups, themes, cursor, selection, status bar
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m54s
Cursor blinking:
- handleFocus() was referenced in TerminalView template but never
  defined in script — clicking the terminal container threw a runtime
  error preventing focus. Added the missing function.
- Removed duplicate handleFocus at end of file

Tool windows:
- CSP simplified for macOS WKWebView compatibility. Previous CSP
  was blocking child WebviewWindow IPC initialization.

RDP tab switch:
- Added rdp_force_refresh command that marks frame_dirty=true and
  clears dirty region, forcing next get_frame to return full buffer
- Called on tab activation and after resize completion
- Eliminates 4-5 second wait for "keyframe" when switching tabs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 10:58:45 -04:00
Vantz Stockwell
38cb1f7430 fix: 6 UX regressions — popups, themes, cursor, selection, status bar
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m53s
Popup windows (tools/editor/help):
- CSP broadened for macOS: added tauri: and https://tauri.localhost to
  default-src, https://ipc.localhost and tauri: to connect-src. WKWebView
  uses different IPC scheme than Windows WebView2.

Theme application:
- terminal.refresh() after theme change forces xterm.js canvas repaint
  of existing text — was only changing background, not text colors

Selection highlighting:
- Removed CSS .xterm-selection div rule entirely — xterm.js v6 canvas
  renderer doesn't use DOM selection divs, the CSS was a no-op that
  conflicted with theme-driven selectionBackground

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 10:08:13 -04:00
Vantz Stockwell
aa2ef88ed7 fix: 6 UX regressions — popups, themes, cursor, selection, status bar
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m51s
Popup windows (tools/editor/help):
- CSP script-src 'self' blocked Tauri's inline IPC bridge scripts in
  child WebviewWindows. Added 'unsafe-inline' to script-src. Still
  restrictive (was null before SEC-4).

Theme application:
- Watcher on sessionStore.activeTheme needed { deep: true } — Pinia
  reactive proxy identity doesn't change on object replacement
- LocalTerminalView.vue had ZERO theme support — added full applyTheme()
  with watcher and mount-time application
- Container background now syncs with theme (was stuck on CSS variable)

Cursor blink:
- terminal.focus() after mount in useTerminal.ts — terminal opened
  without focus, xterm.js rendered static outline instead of blinking block

Selection highlighting:
- applyTheme() was overwriting theme without selectionBackground/
  selectionForeground/selectionInactiveBackground — selection invisible
  after any theme change
- Removed !important from terminal.css that overrode canvas selection
- Bumped default selection opacity 0.3 → 0.4

Status bar:
- h-6 text-[10px] → h-8 text-xs (24px/10px → 32px/12px)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:52:43 -04:00
Vantz Stockwell
b86e2d68d8 refactor: extract keyboard shortcuts composable + 5 UX bug fixes
- Extract handleKeydown into useKeyboardShortcuts.ts composable; reduces
  MainLayout by ~20 lines and isolates keyboard logic cleanly
- ConnectionTree: watch groups for additions and auto-expand new entries
- MonitorBar: generation counter prevents stale event listeners on rapid
  tab switching
- NetworkScanner: revoke blob URL after CSV export click (memory leak)
- TransferProgress: implement the auto-expand/collapse watcher that was
  only commented but never wired up
- FileTree: block binary/large file uploads with clear user error rather
  than silently corrupting — backend sftp_write_file is text-only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 16:53:46 -04:00
Vantz Stockwell
ff9fc798c3 fix: resolve 8 Vue 3 lifecycle and component issues
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 4m5s
VUE-1: store workspace save interval ID, clear in onUnmounted
VUE-2: extract beforeunload handler to named function, remove in onUnmounted
VUE-3: move useTerminal() to <script setup> top level in DetachedSession
VUE-4: call useTerminal() before nextTick await in CopilotPanel launch()
VUE-5: remove duplicate ResizeObserver from LocalTerminalView (useTerminal already creates one)
VUE-6: store terminal.onResize() IDisposable, dispose in onBeforeUnmount
VUE-7: extract connectSsh(), connectRdp(), resolveCredentials() from 220-line connect()
VUE-8: check session protocol before ssh_resize vs pty_resize in TerminalView

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 16:38:00 -04:00
Vantz Stockwell
d78cafba93 feat: terminal_type MCP tool + tab resize fix + close confirmation
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m54s
terminal_type MCP tool (19 tools total):
- Fire-and-forget text input to any session
- Optional press_enter flag (default: true)
- No marker wrapping, no output capture
- Use case: AI sends messages/commands without needing output back

Tab resize fix:
- Double requestAnimationFrame before fitAddon.fit() on tab switch
- Container has real dimensions after browser layout pass
- Also sends ssh_resize/pty_resize to backend with correct cols/rows
- Fixes 6-8 char wide terminals after switching tabs

Close confirmation:
- beforeunload event shows browser "Leave page?" dialog
- Only triggers if sessions are active
- Synchronous — cannot hang the close like onCloseRequested did

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:21:53 -04:00
Vantz Stockwell
d39c0d38ed fix: local PowerShell garbled output + resize not propagating
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 4m10s
Two issues:
1. convertEol was false for PTY sessions, but Windows ConPTY sends
   bare \n without \r. Now enabled on Windows PTY sessions (checked
   via navigator.platform). Unix PTY still false (driver handles it).

2. LocalTerminalView had no ResizeObserver, so the terminal never
   reflowed when the container size changed. Added ResizeObserver
   matching the SSH TerminalView pattern. Also added proper cleanup
   on unmount.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:38:24 -04:00
Vantz Stockwell
4532f3beb6 feat: local terminal tabs — + button spawns WSL/Git Bash/PowerShell/CMD
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 16s
The + button in the tab bar now shows a dropdown of detected local
shells. Clicking one opens a full-size PTY terminal in the main
content area as a proper tab — not the copilot sidebar.

- New "local" protocol type in Session interface
- LocalTerminalView component uses useTerminal(id, 'pty')
- SessionContainer renders local sessions alongside SSH/RDP
- TabBadge shows purple dot for local sessions
- Shell detection includes WSL (wsl.exe) on Windows
- closeSession handles PTY disconnect for local tabs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:46:09 -04:00
Vantz Stockwell
2ad6da43eb feat: remote monitoring bar + SFTP tab follow + CWD macOS fix
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 15s
Remote monitoring bar:
- Slim 24px bar at bottom of every SSH terminal
- CPU, RAM, disk, network stats polled every 5s via exec channel
- Cross-platform: Linux (/proc), macOS (vm_stat/sysctl), FreeBSD
- Color-coded thresholds: green/amber/red
- No agent installation — standard POSIX commands only

SFTP follows active tab:
- Added :key="activeSessionId" to FileTree component
- Vue recreates FileTree when session changes, reinitializing SFTP

CWD tracking fix (macOS + all platforms):
- Old approach: exec channel pwd — returns HOME, not actual CWD
- New approach: passive OSC 7 parsing in the output stream
- Scans for \e]7;file://host/path\a without modifying data
- Works with bash, zsh, fish on both Linux and macOS
- Zero corruption risk — data passes through unmodified
- Includes URL percent-decoding for paths with spaces

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:38:01 -04:00
Vantz Stockwell
2dfe4f9d7a fix: focus terminal on mount so keyboard input works immediately
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
The watch on isActive never fired on initial mount because the value
starts as true (Vue watch only triggers on changes). Added explicit
focus + fit in onMounted with a short delay for DOM readiness.
Also added @click handler on container as fallback focus mechanism.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:47:16 -04:00
Vantz Stockwell
0cd4cc0f64 feat: Phase 5 complete — themes, editor, shortcuts, workspace, settings
Theme service: 7 built-in themes seeded from Rust, ThemePicker
loads from backend. Workspace service: save/load snapshots, crash
recovery detection. SettingsModal: full port with Tauri invoke.
CommandPalette, HostKeyDialog, ConnectionEditDialog all ported.

CodeMirror editor: inline above terminal, reads/writes via SFTP.
Full keyboard shortcuts: Ctrl+K/W/Tab/Shift+Tab/1-9/B/F.
Terminal search bar via Ctrl+F (SearchAddon).
Tab badges: protocol dots, ROOT warning, environment pills.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:36:06 -04:00
Vantz Stockwell
737491d3f0 feat: Phase 2 complete — SSH terminal + frontend UI
Rust SSH service: russh async client, DashMap session registry,
TOFU host key verification, CWD tracking via separate exec channel
(never touches terminal stream), base64 event emission for terminal
I/O. 52/52 tests passing.

Vue 3 frontend: ported from Wails v3 to Tauri v2 — useTerminal
composable with streaming TextDecoder + rAF batching, session store
with multi-connection support, connection store/tree, sidebar, tab
bar, status bar, keyboard shortcuts. All Wails imports replaced
with Tauri API equivalents.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:28:18 -04:00