# Copilot Instructions — Nexus Terminal ## Build & Test ```bash make deps # go mod download + npm install make build # production build → build/bin/nexus-terminal.app make dev # wails dev with hot reload make test # go test ./... -v -count=1 make lint # golangci-lint run ./... # Single package test go test ./internal/storage/ -v -count=1 -run TestProfileCRUD ``` The frontend has no separate build step — `npm run build` (called by Wails) copies xterm vendor libs from `node_modules` into `frontend/src/js/lib/` and `frontend/src/css/lib/`. All frontend assets are embedded at compile time via `frontend/embed.go`. ## Architecture Wails v2 desktop app: Go backend + HTML/CSS/JS frontend rendered in a native webview (WKWebView on macOS). **Go backend** (`internal/`): - `app/` — lifecycle bootstrap: opens SQLite, inits secret stores, wires everything together - `api/` — single `Service` struct bound to Wails; every public method is callable from JS as `window.go.api.Service.MethodName()` - `sessions/` — manages concurrent protocol sessions; owns SSH/Telnet/RAW/GitHub client lifecycles - `storage/` — SQLite repository (WAL mode) with embedded sequential migrations in `storage/migrations/` - `secrets/` — two-tier credential storage: OS keychain (preferred) → AES-256-GCM encrypted file vault (fallback) - `models/` — shared domain types and defaults; protocol configs are JSON-encoded in the DB - `sshclient/`, `telnetclient/`, `rawclient/`, `githubclient/` — protocol implementations **Frontend** (`frontend/`): - Plain HTML/CSS/JS — no framework, no bundler, no ES modules - `index.html` is the app shell; loads CSS then JS in strict order - `src/js/` — 13 modules, each IIFE-wrapped, exporting to `window.NexusTerminal` - `src/css/` — modular stylesheets; `tokens.css` defines all design tokens - Vendor libs (xterm.js, addons) live in `src/js/lib/` and `src/css/lib/` — auto-copied, gitignored **Go ↔ JS communication:** - **Synchronous:** Frontend calls `window.go.api.Service.*()` (returns Promise) - **Asynchronous:** Backend pushes events via `wailsRuntime.EventsEmit()`; frontend listens with `window.runtime.EventsOn()` - **Bidirectional events** for secret prompts and host key verification: backend emits a request event with a `requestID`, frontend shows a modal, then emits a response event with the same ID. The Go side blocks on a channel keyed by that ID. Key events: `session:data`, `session:state`, `session:closed`, `session:raw:data`, `session:github:repos`, `session:secret:prompt`/`session:secret:response`, `session:hostkey:verify`/`session:hostkey:response`. ## WKWebView Constraints (Critical) The macOS webview silently blocks or breaks several standard web APIs. These constraints affect every frontend change: 1. **No `window.confirm()`, `window.prompt()`, `window.alert()`** — they either return false/null silently or do nothing. All user prompts must use the custom modal system (DOM-based backdrop + modal with `is-visible` class toggling). 2. **No ES modules** — `