Commit Graph

50 Commits

Author SHA1 Message Date
Vantz Stockwell
0251614732 fix: trigger initial CWD emission with cd . after OSC 7 hook inject
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 6s
precmd/PROMPT_COMMAND only fire after a command runs. Without cd .
the first OSC 7 never emits and SFTP doesn't know the initial directory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:18:35 -04:00
Vantz Stockwell
0bcf59865d fix: hide OSC 7 hook injection from terminal output
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 6s
The CWD hook command was visible to the user. Now wrapped in
stty -echo/echo to suppress echo, followed by clear to wipe the
screen. Space prefix prevents history recording in most shells.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:16:20 -04:00
Vantz Stockwell
3e548ed10e feat: SFTP editor opens as popup window instead of inline overlay
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 6s
Right-click → Edit now opens a separate Tauri window with the file
content in a monospace editor. Ctrl+S saves back to remote via SFTP.
Tab inserts 4 spaces. Modified indicator in toolbar.

Removed the inline EditorWindow overlay that covered the terminal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:58:09 -04:00
Vantz Stockwell
016906fc9d fix: add window/webview creation permissions for tool popup windows
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
Tauri v2 ACL requires explicit permissions to create windows from the
frontend. Added core🪟allow-create and
core:webview:allow-create-webview-window so the Tools menu can open
popup windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:56:34 -04:00
Vantz Stockwell
0e88f9f07c feat: file-based logging to wraith.log for MCP startup diagnostics
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
env_logger was never initialized so log::info/error went nowhere.
Added write_log() that appends to data_dir/wraith.log with timestamps.
Logs MCP server startup success/failure and any panics.

Check: %APPDATA%\Wraith\wraith.log (Windows)
       ~/Library/Application Support/Wraith/wraith.log (macOS)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:55:31 -04:00
Vantz Stockwell
44c79decf3 fix: SFTP preserves position on tab switch + CWD following on macOS
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m58s
SFTP tab switch fix:
- Removed :key on FileTree that destroyed component on every switch
- useSftp now accepts a reactive Ref<string> sessionId
- Watches sessionId changes and reinitializes without destroying state
- Per-session path memory via sessionPaths map — switching back to a
  tab restores exactly where you were browsing

CWD following fix (macOS + all platforms):
- Injects OSC 7 prompt hook into the shell after SSH connect
- zsh: precmd() emits \e]7;file://host/path\e\\
- bash: PROMPT_COMMAND emits the same sequence
- Sent via the PTY channel so it configures the interactive shell
- The passive OSC 7 parser in the output loop picks it up
- SFTP sidebar auto-navigates to the current working directory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:41:50 -04:00
Vantz Stockwell
c507c515ef fix: wrap MCP/error watcher startup in catch_unwind — never crash app
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m1s
The MCP server and error watcher are nice-to-have services that were
crashing the app on startup. Wrapped in catch_unwind + error handling
so a failure in these subsystems logs an error instead of taking down
the entire application.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:30:49 -04:00
Vantz Stockwell
15055aeb01 feat: all 18 tools exposed as MCP tools for AI copilot
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 6s
Every tool in Wraith is now callable by the AI through MCP:

| MCP Tool          | AI Use Case                              |
|-------------------|------------------------------------------|
| network_scan      | "What devices are on this subnet?"       |
| port_scan         | "Which servers have SSH open?"           |
| ping              | "Is this host responding?"               |
| traceroute        | "Show me the route to this server"       |
| dns_lookup        | "What's the MX record for this domain?"  |
| whois             | "Who owns this IP?"                      |
| wake_on_lan       | "Wake up the backup server"              |
| bandwidth_test    | "How fast is this server's internet?"    |
| subnet_calc       | "How many hosts in a /22?"               |
| generate_ssh_key  | "Generate an ed25519 key pair"           |
| generate_password | "Generate a 32-char password"            |
| terminal_read     | "What's on screen right now?"            |
| terminal_execute  | "Run df -h on this server"               |
| terminal_screenshot| "What's that RDP error?"                |
| sftp_list/read/write| "Read the nginx config"               |
| list_sessions     | "What sessions are active?"              |

11 new HTTP endpoints on the MCP server. 11 new tool definitions
in the bridge binary. The AI doesn't just chat — it scans, discovers,
analyzes, and connects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:15:08 -04:00
Vantz Stockwell
b3f56a2729 feat: Tools R2 — DNS, Whois, Bandwidth, Subnet Calculator
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 7s
4 new tools with full backend + popup UIs:

DNS Lookup:
- dig/nslookup/host fallback chain on remote host
- Record type selector (A, AAAA, MX, NS, TXT, CNAME, SOA, SRV, PTR)

Whois:
- Remote whois query, first 80 lines
- Works for domains and IP addresses

Bandwidth Test (2 modes):
- iperf3: LAN speed test between remote host and iperf server
- Internet: speedtest-cli / curl-based Cloudflare test fallback

Subnet Calculator:
- Pure Rust, no SSH needed
- CIDR input with quick-select buttons (/8 through /32)
- Displays: network, broadcast, netmask, wildcard, host range,
  total/usable hosts, class, private/public

Tools menu now has 11 items across 3 sections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:12:11 -04:00
Vantz Stockwell
875dd1a28f feat: complete Tools suite — 7 tool UIs in popup windows
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 6s
All 7 tool windows with full UIs:
- Network Scanner: subnet scan, ARP+DNS discovery, results table with
  Quick Scan per host, SSH/RDP connect buttons, CSV export
- Port Scanner: custom range or quick scan (24 common ports), open/closed
  results table with service names
- Ping: remote ping with count, raw output display
- Traceroute: remote traceroute, raw output display
- Wake on LAN: MAC address input, broadcasts via python3 on remote host
- SSH Key Generator: ed25519/RSA, copy public/private key, fingerprint
- Password Generator: configurable length/charset, copy button, history

Architecture:
- App.vue detects tool mode via URL hash (#/tool/name?sessionId=...)
- ToolWindow.vue routes to correct tool component
- Tools menu in toolbar opens Tauri popup windows (WebviewWindow)
- Capabilities grant tool-* windows the same permissions as main
- SFTP context menu: right-click Edit/Download/Rename/Delete

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:07:15 -04:00
Vantz Stockwell
5cc412a251 feat: Tools menu + backend commands for all tools
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m2s
Tools menu in toolbar (next to File) with 7 tools:
- Network Scanner (existing scan_network command)
- Port Scanner (existing scan_ports/quick_scan commands)
- Ping — via SSH exec channel, cross-platform
- Traceroute — via SSH exec channel
- Wake on LAN — broadcasts WoL magic packet via python3 on remote host
- SSH Key Generator — pure Rust ed25519/RSA keygen via ssh-key crate
- Password Generator — cryptographic random with configurable charset

Backend: all 5 new Tauri commands (tool_ping, tool_traceroute,
tool_wake_on_lan, tool_generate_ssh_key, tool_generate_password)

Frontend: Tools dropdown menu wired, popup window launcher ready.
Tool window UIs (the actual panels inside each popup) to follow.

SFTP context menu: right-click Edit/Download/Rename/Delete working.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:03:34 -04:00
Vantz Stockwell
2d0964f6b2 feat: network scanner + SFTP context menu + CI fix
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m7s
Network scanner (through SSH exec channels):
- scan_network: ping sweep + ARP table + reverse DNS on remote network
- scan_ports: TCP connect scan via bash /dev/tcp (parallel batches of 20)
- quick_scan: 24 common ports (SSH, HTTP, RDP, SMB, DB, etc.)
- Cross-platform: Linux + macOS
- No agent/nmap required — uses standard POSIX commands
- All scans run on the remote host through existing SSH tunnel

SFTP context menu:
- Right-click on files/folders shows Edit, Download, Rename, Delete
- Right-click on folders shows Open Folder
- Teleport menu to body for proper z-index layering
- Click-away handler to close menu
- Rename uses sftp_rename invoke

CI fix:
- Added default-run = "wraith" to Cargo.toml
- The [[bin]] entry for wraith-mcp-bridge confused Cargo about which
  binary is the Tauri app main binary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:56:42 -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
bc608b0683 feat: copilot QoL — resizable panel, SFTP tools, context, error watcher
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 15s
Resizable panel:
- Drag handle on left border of copilot panel
- Pointer events for smooth resize (320px–1200px range)

SFTP MCP tools:
- sftp_list: list remote directories
- sftp_read: read remote files
- sftp_write: write remote files
- Full HTTP endpoints + bridge tool definitions

Active session context:
- mcp_get_session_context command returns last 20 lines of scrollback
- Frontend can call on tab switch to keep AI informed

Error watcher:
- Background scanner runs every 2 seconds across all sessions
- 20+ error patterns (permission denied, OOM, segfault, disk full, etc.)
- Emits mcp:error events to frontend with session ID and matched line
- Sessions auto-registered with watcher on connect

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:30:12 -04:00
Vantz Stockwell
add0f0628f feat: MCP auto-inject + RDP screenshot tool
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 16s
- Auto-inject CLAUDE_MCP_SERVERS env var when copilot PTY spawns,
  so Claude Code auto-discovers wraith-mcp-bridge without manual config
- RDP screenshot_png_base64() encodes frame buffer as PNG via png crate
- Bridge binary exposes terminal_screenshot tool returning MCP image
  content (base64 PNG with mimeType) for multimodal AI analysis
- MCP session list now includes RDP sessions with dimensions
- /mcp/screenshot HTTP endpoint on the internal server

"Screenshot that RDP session, what's the error?" now works.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:17:36 -04:00
Vantz Stockwell
8276b0cc59 feat: MCP bridge binary + HTTP server + auto-config injection
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 16s
Complete MCP communication pipeline:

Backend HTTP server (axum on localhost:0):
- POST /mcp/sessions — list active sessions
- POST /mcp/terminal/read — read scrollback (ANSI stripped)
- POST /mcp/terminal/execute — send command + marker, capture output
- Port written to data_dir/mcp-port at startup
- Shares SshService and ScrollbackRegistry with AppState via Clone

Bridge binary (wraith-mcp-bridge):
- Speaks JSON-RPC 2.0 over stdio (MCP protocol)
- Translates tool calls to HTTP requests against running Wraith
- Implements initialize, tools/list, tools/call
- Exposes: terminal_read, terminal_execute, list_sessions
- Reads MCP port from data_dir/mcp-port

Auto-config:
- PTY spawn injects WRAITH_MCP_BRIDGE env var
- SshService and ScrollbackRegistry derive Clone for sharing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:10:09 -04:00
Vantz Stockwell
a3a7116f00 feat: MCP Phase 1 — scrollback buffer, terminal_read, terminal_execute
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m52s
Infrastructure for the Wraith Terminal MCP server:

- ScrollbackBuffer: 64KB circular buffer per session with ANSI stripping
- ScrollbackRegistry: DashMap registry shared between output loops and MCP
- SSH output loop feeds scrollback in addition to emitting events
- PTY output loop feeds scrollback in addition to emitting events
- mcp_terminal_read: read last N lines from any session (ANSI stripped)
- mcp_terminal_execute: send command + marker, capture output until marker
- mcp_list_sessions: enumerate all active SSH sessions with metadata

8 new scrollback tests (ring buffer, ANSI strip, line limiting).
95 total tests, zero warnings.

Bridge binary and auto-config injection to follow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:00:32 -04:00
Vantz Stockwell
8df59683d2 fix: disable Tauri file drop handler — unblocks HTML5 drag-and-drop
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m4s
Tauri's built-in dragDropEnabled intercepts all drag events in the
WebView for native file drop handling. This prevents HTML5 drag-and-drop
between elements within the page. Disabled so tab reordering works.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:48:46 -04:00
Vantz Stockwell
37c9b46a51 fix: PTY crash — use std:🧵:spawn instead of tokio::spawn_blocking
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m49s
tokio::task::spawn_blocking panics when called without a tokio runtime
context. Sync Tauri command handlers may not have one. The PTY reader
loop is long-lived anyway — std:🧵:spawn is more correct for
persistent blocking I/O and doesn't require a runtime guard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:13:42 -04:00
Vantz Stockwell
512347af5f feat: Local PTY Copilot Panel — replace Gemini stub with real terminal
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m6s
Ripped out the Gemini API stub (ai/mod.rs, ai_commands.rs, GeminiPanel.vue)
and replaced it with a local PTY terminal in the sidebar panel. Users select
a shell (bash/zsh/sh on Unix, PowerShell/CMD/Git Bash on Windows), launch it,
and run claude/gemini/codex or any CLI tool directly.

Backend:
- New PtyService module using portable-pty (cross-platform PTY)
- DashMap session registry (same pattern as SshService)
- spawn_blocking output loop (portable-pty reader is synchronous)
- 5 Tauri commands: list_available_shells, spawn_local_shell, pty_write,
  pty_resize, disconnect_pty

Frontend:
- Parameterized useTerminal composable: backend='ssh'|'pty'
- convertEol=false for PTY (PTY driver handles LF→CRLF)
- CopilotPanel.vue with shell selector, launch/kill, session ended prompt
- Ctrl+Shift+G toggle preserved

Tests: 87 total (5 new PTY tests), zero warnings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:43:18 -04:00
Vantz Stockwell
eda36c937b fix: pure Rust EC key decryption — no openssl dependency
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m3s
Replaced the openssl CLI fallback with pure Rust crypto for EC private
keys in SEC1 format (-----BEGIN EC PRIVATE KEY-----). Handles PKCS#5
encrypted keys (AES-128-CBC + MD5 EVP_BytesToKey KDF) and converts to
PKCS#8 PEM that russh can parse natively.

All crypto crates (md5, aes, cbc, sec1, pkcs8) were already in the dep
tree via russh — just promoted to direct dependencies. Zero new binary
dependencies, works on Windows without openssl installed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:08:55 -04:00
Vantz Stockwell
74b9be3046 fix: remove desktop shortcut from NSIS installer by default
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
Tauri's NSIS bundler creates a desktop shortcut unconditionally. Added
a POSTINSTALL hook that deletes it immediately after creation. Start
menu shortcut remains. Users who want a desktop shortcut can create
one manually.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:04:06 -04:00
Vantz Stockwell
4a0c2c9790 fix: SSH key auth — handle EC/DSA keys via openssl pkey fallback
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
russh only parses 4 PEM headers: OPENSSH, RSA, PKCS8, ENCRYPTED PKCS8.
EC keys (-----BEGIN EC PRIVATE KEY-----) with PKCS5 encryption silently
failed with "Could not read key".

Fix adds two fallbacks:
1. If russh can't parse the key, convert to PKCS8 via `openssl pkey`
   which handles EC, DSA, and all other OpenSSL-supported formats
2. If the input doesn't start with -----BEGIN, try reading it as a
   file path (supports ~ expansion) for keys stored on disk

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:18:01 -04:00
Vantz Stockwell
633087633e test: full test coverage — 82 tests across all modules, zero warnings
Added tests for 3 uncovered modules:
- db: open, migrate, idempotent migration, FK/WAL pragmas, clone shares conn
- theme: seed_builtins (7 themes), idempotent seed, get_by_name, hex color
  validation, sort ordering, case sensitivity
- rdp/input: scancode lookup, extended key detection, value extraction,
  mouse flag composition, map coverage assertion

Existing test count: 52 (vault, connections, credentials, settings, host_keys)
New tests added: 30
Total: 82 tests, all passing, zero compiler warnings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:33:36 -04:00
Vantz Stockwell
8c431d3d12 fix: SSH input deadlock — output loop held channel mutex across await
Root cause: The output reader loop held Arc<TokioMutex<Channel>> while
calling ch.wait().await. After the initial prompt rendered and the server
went idle, wait() blocked indefinitely holding the lock. ssh_write()
could never acquire the mutex to send keystrokes. Permanent deadlock.

Fix: Separated read/write paths. The output loop now owns the Channel
exclusively via tokio::select!, receiving resize/shutdown commands through
an mpsc channel. Writes go through Handle::data(channel_id, data) which
bypasses the Channel entirely — no shared mutex, no deadlock.

Also killed all compiler warnings (unused imports in rdp module).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:28:09 -04:00
Vantz Stockwell
99ecbe739e feat: RDP clipboard paste, keyboard grab default ON, frame dirty flag
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m49s
1. Clipboard paste (rdp_send_clipboard): simulates typing each character
   via scancode key press/release events. Full ASCII coverage including
   all symbols, numbers, and shifted characters. Handles 32-char
   generated passwords without manual typing.

2. Keyboard grab defaults to ON so RDP sessions accept keyboard input
   immediately without requiring the user to click the toolbar toggle.

3. Frame dirty flag: GraphicsUpdate sets an AtomicBool, get_frame only
   encodes + returns base64 when dirty (returns empty string otherwise).
   Eliminates ~8MB/frame base64 encoding on unchanged frames at 30fps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:57:16 -04:00
Vantz Stockwell
ffe79e9a54 fix: add Tauri v2 capabilities — unblock event:listen for SSH terminal
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m50s
The app had no capabilities file, so Tauri v2's ACL blocked all
frontend listen() calls. SSH connections succeeded on the Rust side
but the terminal never received data events, appearing as "nothing
happened." Grants core:default, core:event:default, core🪟default,
and shell:allow-open.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:00:54 -04:00
Vantz Stockwell
6e33bbdcf1 fix: serialize tags as array (not JSON string), DevTools debug-only
- ConnectionRecord.tags changed from String to Vec<String> so the
  frontend receives a proper array instead of a raw JSON string.
  The old behavior caused v-for to iterate characters, corrupting
  the connection display in the sidebar.
- DevTools now only auto-opens in debug builds (cfg(debug_assertions)),
  not in production.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:58:58 -04:00
Vantz Stockwell
e28d0f65cd feat: integrate Gemini AI XO copilot + backend cleanup + connection timeouts
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 9s
Backend cleanup (Gemini):
- Strip verbose doc comments across SSH, RDP, and command modules
- Add 10s timeout on SSH connect/auth, 15s on RDP connection
- Fix macOS data directory to ~/Library/Application Support/Wraith
- Add generic disconnect_session command
- Simplify SFTP setup and error handling
- Inline AppState field construction

Gemini AI XO integration:
- Add GeminiService (src-tauri/src/ai/) with API Key, Service Account,
  and Google Account (OAuth2) authentication methods
- Add ai_commands (set_gemini_auth, gemini_chat, is_gemini_authenticated)
- Add GeminiPanel.vue — collapsible chat sidebar with multi-auth UI
- Wire Ctrl+Shift+G toggle and status bar AI button in MainLayout
- Add reqwest + anyhow dependencies

Bugfix:
- Fix dropped modulo operator in Ctrl+Tab/Ctrl+Shift+Tab handlers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:38:52 -04:00
Vantz Stockwell
8e335f92b5 refactor: clean up backend — strip verbose docs, add connection timeouts, fix macOS data dir
- Remove redundant doc comments and section headers across SSH, RDP, and command modules
- Add 10s timeout on SSH connect/auth, 15s timeout on RDP connection
- Fix macOS data directory to use ~/Library/Application Support/Wraith
- Add generic disconnect_session command alongside disconnect_ssh
- Simplify SFTP setup and RDP error handling
- Add explicit label/url to main window config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:30:02 -04:00
Vantz Stockwell
429f41d853 fix: auto-patch tauri.conf.json version from git tag in CI
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m48s
Never manually sync version again. CI reads the tag, patches
the config before building. Also bumped to 1.1.5.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 03:37:30 -04:00
Vantz Stockwell
0cdc865483 debug: enable DevTools in release builds
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m44s
Added devtools Cargo feature, auto-open DevTools on startup
so we can see frontend console errors on Windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 03:23:59 -04:00
Vantz Stockwell
6c7b277494 fix: SSH auth — decrypt credentials from vault before connecting
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 6s
Added decrypt_password and decrypt_ssh_key Tauri commands.
Connect flow now resolves credentialId → decrypted credentials
from the vault. Falls back to window.prompt on auth failure.
Fixed case-sensitive error string matching.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 03:04:47 -04:00
Vantz Stockwell
9cf64f99c7 fix: remove updater plugin — missing pubkey crashes on startup
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m41s
Will re-enable after generating Tauri signing keypair.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 02:40:55 -04:00
Vantz Stockwell
8602f1779b debug: add file-based startup log to diagnose silent crash
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m47s
Writes to %APPDATA%\Wraith\wraith-startup.log since release
builds suppress all console output via windows_subsystem.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 02:35:08 -04:00
Vantz Stockwell
db1bd39030 fix: bump version in tauri.conf.json to 1.1.0
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m49s
Tauri uses this for the installer filename, not the git tag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 02:29:02 -04:00
Vantz Stockwell
4eb304222d fix: use Tauri bundler for NSIS — runner now under ActRunner account
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 5m30s
Re-enable Tauri NSIS bundler (embeds frontend in exe). Runner
runs as ActRunner service account with proper user profile,
so Tauri's downloaded NSIS/tools should work. Removed manual
NSIS step and template file from workflow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 02:17:28 -04:00
Vantz Stockwell
15ee82ef53 fix: move NSIS script to template file — avoid YAML !include parse error
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m43s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 02:01:42 -04:00
Vantz Stockwell
5910e7a849 fix: skip Tauri bundler, build NSIS installer manually
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 2m34s
Tauri's bundled makensis can't run under SYSTEM account.
Use --no-bundle, then build installer with system NSIS
directly — same pattern as the old Go pipeline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:47:16 -04:00
Vantz Stockwell
84a2fc8618 fix: bundle target NSIS only — skip WiX/MSI
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 2m34s
WiX candle.exe fails under SYSTEM account. NSIS is all we need.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:18:53 -04:00
Vantz Stockwell
08ebf35c66 fix: NSIS installMode perMachine — install to Program Files
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 1m39s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 17:43:01 -04:00
Vantz Stockwell
47fb066f1d docs: Phase 7 complete — CLAUDE.md + Go migration checklist
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
CLAUDE.md for future XOs: tech stack, architecture, commands,
key design decisions, lineage from Go version.

GO_MIGRATION.md: step-by-step checklist for deploying v2,
archiving Go repo, configuring CI secrets, first release.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:48:36 -04:00
Vantz Stockwell
bb5b9469d1 feat: Phase 6 complete — CI/CD pipeline + auto-updater
Gitea Actions workflow: Tauri build on Windows, Azure Key Vault
EV code signing via jsign, NSIS installer, Gitea package upload,
release creation with v-prefixed tag. Tauri updater plugin wired
with Gitea releases endpoint. Shell plugin configured for open().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:39:42 -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
c75da74ecd feat: Phase 4 complete — RDP via ironrdp
Rust RDP service: ironrdp client with full connection handshake
(TCP -> TLS -> CredSSP -> NLA), pixel buffer frame delivery,
mouse/keyboard input via scancode mapping, graceful disconnect.
Runs in dedicated thread with own tokio runtime to avoid Send
lifetime issues with ironrdp trait objects.

Vue frontend: RdpView canvas renderer with 30fps polling,
mouse/keyboard capture, RdpToolbar with Ctrl+Alt+Del and
clipboard. SessionContainer handles both SSH and RDP tabs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:05:11 -04:00
Vantz Stockwell
a8656b0812 feat: Phase 3 complete — SFTP sidebar with full file operations
Rust SFTP service: russh-sftp client on same SSH connection,
DashMap storage, list/read/write/mkdir/delete/rename/stat ops.
5MB file size guard. Non-fatal SFTP failure (terminal still works).

Vue frontend: FileTree with all toolbar buttons wired (upload,
download, delete, mkdir, refresh), TransferProgress panel,
useSftp composable with CWD following via Tauri events.
MainLayout wired with SFTP sidebar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:46:35 -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
Vantz Stockwell
0802ae0753 chore: add .gitignore, remove node_modules and target from tracking 2026-03-17 15:10:00 -04:00
Vantz Stockwell
2848d79915 feat: Phase 1 complete — Tauri v2 foundation
Rust backend: SQLite (WAL mode, 8 tables), vault encryption
(Argon2id + AES-256-GCM), settings/connections/credentials
services, 19 Tauri command wrappers. 46/46 tests passing.

Vue 3 frontend: unlock/create vault flow, Pinia app store,
Tailwind CSS v4 dark theme with Wraith branding.

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