# NexusOps — Make-It-Perfect Plan Target: `/root/agent-dashboard` on c2-builder-slay (10.30.20.44) Rule: remove no features. Only add and fix. --- ## PHASE 1 — FIX (make everything that exists actually work) ### 1.1 Screenshot/Exfil/Harvest results viewer (the real gap — pipelines WORK, results invisible) Verified: screenshot → `/api/agent/file-result` → `exfiltratedFiles` → `/api/files` ✅ Verified: harvest → `/api/agent/harvest-result` → `/api/credentials` ✅ **The frontend has the trigger buttons (Exfil & Harvest tab) but NEVER fetches `/api/files` or `/api/credentials`.** Data lands server-side and goes invisible. - New **Loot** section in the dashboard: two tabs (Files / Credentials). - Files: table (node, filename, mime, size, time, download btn). Images (screenshots) get inline thumbnails + lightbox. - Credentials: grouped by node+type, masked by default, click-to-reveal, copy button, CSV export (endpoint exists). - Live-update both via the existing WebSocket broadcast (add files/creds summary counts to `NODES_UPDATE` payload, or poll on event). - "Loot received" toast when a new file/cred batch arrives. ### 1.3 Dashboard auth (currently wide open) - Add session-token middleware to server.js: `NEXUS_AUTH_TOKEN` env var; on first load the UI asks for the token once, stores in localStorage, sends as `Authorization: Bearer`. - Whitelist: agent endpoints (`/api/agent/*`, `/install*`, `/agent.py`) use a separate agent token embedded at install time. Dashboard/API/export endpoints require the operator token. - WebSocket: token passed as query param on upgrade. ### 1.4 Server as a real service - systemd unit `nexusops-dashboard.service`: node server.js, Restart=always, env file `/root/agent-dashboard/.env` (PORT, PUBLIC_URL, NEXUS_AUTH_TOKEN). - systemd unit `nexusops-tunnel.service`: cloudflared tunnel for `agent.thetempleofdoom.com` (tunnel creds already on the box — find via `cloudflared tunnel list`). - `systemctl enable --now` both. Verify reboot survival. ### 1.5 Persistence hardening - Replace JSON-file saves with atomic writes (`write tmp → rename`) + a single-writer lock. - Move to SQLite (`better-sqlite3`) for nodes/metrics/commands/files/creds — keeps all current data shapes, migration script imports existing `data/*.json` on first boot. - Keeps JSON export endpoints untouched. ### 1.6 WebSocket resilience - Frontend: reconnect with exponential backoff (1s→2s→5s→30s cap), visible "reconnecting" pill in nav, full state resync on reconnect. - Server: heartbeat ping every 25s so proxies/CF don't kill idle sockets. ### 1.7 Agent robustness - Verify `--silent` flag actually suppresses output (install scripts rely on it). - Input capture: if `pynput` missing, agent logs one clear line to server (`input capture unavailable`) instead of silent degradation; dashboard shows the capability as "unavailable" on the node card instead of nothing. - Agent auto-reconnect on server restart (already partially there — verify backoff doesn't spin at 100% CPU). - Add agent version string; server tracks it per node; "update agent" skips already-current nodes. ### 1.8 Empty state + first-run UX - Dashboard with zero nodes → hero panel with the universal one-liner + QR code (qrcode.js, local) pointing at the public install URL. - First node connects → confetti-free but noticeable highlight animation. --- ## PHASE 2 — POLISH (the feel) ### 2.1 Design system pass - Consolidate to CSS custom properties (colors, spacing, radius, glow) — file already has some; finish the job. - Typography: JetBrains Mono for terminal/data, Inter for UI chrome. - Online nodes: subtle emerald pulse ring. Offline: desaturated, grayscale icon. - Consistent 8px spacing grid; kill stray one-off margins. ### 2.2 Node cards upgrade - Inline SVG sparklines (last 30 heartbeats) for CPU + MEM on each card. - Relative timestamps ("last seen 12s ago") ticking live. - Click card → slide-in **detail drawer**: full metrics chart, files/creds/screenshots scoped to that node, command console pinned to it, tag editor, ping button with latency readout. - Right-click (or ⋮ menu): ping, screenshot, update agent, reboot, kill agent, unregister — with confirm modals for destructive ones. ### 2.3 Command builder - Structured action picker: dropdown of every agent action (raw_command, manage_service, screenshot, download_file, harvest_credentials, update_agent, …) with a per-action form (service name, file path, etc.) instead of making the operator type raw JSON. - Terminal output viewer: ANSI color support, mono font, copy button, per-command expandable rows in audit log. - Bulk commands: tag-based targeting ("all linux nodes", "tag=prod") with live preview of affected nodes before send. ### 2.4 Global polish - Keyboard shortcuts: `/` focus search, `i` installer modal, `k` kill switch (with confirm), `Esc` close modals. `?` shows shortcut overlay. - Toasts (top-right) for: node came online, node went offline, command completed/failed, file received, creds received. - Loading skeletons for every section on first paint. - Mobile responsive: cards stack, drawer becomes full-screen modal, terminal scrolls horizontally. - Nav shows live clock + server latency (WS round-trip). --- ## PHASE 3 — ADD (new, no removals) ### 3.1 Scheduled commands - `node-cron` in server: schedule raw/structured commands per node/tag on cron expressions. UI: simple scheduler panel (time picker + action + target). Persisted in SQLite. ### 3.2 Screenshot watch mode - "Watch" mode: request screenshot every N seconds from one node, stream into the drawer (pseudo-live). Gallery itself ships with the Loot viewer in 1.1. ### 3.3 Webhook alerts - Config panel: webhook URL (n8n on .236 / Discord / generic). - Events: node online/offline, new node registered, creds harvested, command failed. - Server POSTs JSON event; n8n routes to Telegram/iMessage. ### 3.4 Cross-platform binaries - GitHub Actions (or local runners): build NexusAgent.exe (Windows) + NexusAgent-mac (macOS arm64/x64 universal2) on release. - Binary tab becomes real: per-OS download buttons with version + build date. - Fallback: keep "binary only exists for Linux x64" honest until then (grey out, tooltip). ### 3.5 Node grouping & tags - Tag management UI: create/rename/delete tags, drag nodes between groups, group-level bulk actions. - Saved filters ("show me prod-linux only"). ### 3.6 Audit & export upgrades - Audit log: filter by node/status/action, date range, export filtered CSV. - Full-data export (one zip: nodes, commands, files, creds, inputs, logs). ### 3.7 Health watchdog for the stack itself - Cron on the MacBook: every 5 min hit `https://agent.thetempleofdoom.com/api/status`; if down → restart services via SSH, alert via existing n8n/Telegram path. --- ## EXECUTION ORDER (suggested) | # | Item | Phase | Effort | |---|------|-------|--------| | 1 | Server + tunnel systemd units | 1.4 | 15 min | | 2 | Dashboard auth token | 1.3 | 45 min | | 3 | Loot viewer (files + creds + screenshot gallery) | 1.1 | 2 h | | 4 | WebSocket reconnect | 1.6 | 30 min | | 5 | Empty state + QR install | 1.8 | 45 min | | 6 | Atomic saves → SQLite | 1.5 | 2 h | | 7 | Agent version + capability reporting | 1.7 | 1 h | | 8 | Design system + node cards + drawer | 2.1–2.2 | 3 h | | 9 | Command builder + bulk targeting | 2.3 | 2 h | | 10 | Shortcuts, toasts, skeletons, mobile | 2.4 | 2 h | | 11 | Scheduled commands | 3.1 | 1.5 h | | 12 | Webhook alerts | 3.3 | 1 h | | 13 | Screenshot watch mode (live refresh in drawer) | 3.2 | 1 h | | 14 | Tags/groups UI | 3.5 | 1.5 h | | 15 | Cross-platform binaries | 3.4 | 3 h | | 16 | Audit/export upgrades | 3.6 | 1 h | | 17 | Self-watchdog | 3.7 | 30 min | **Ship gate after Phase 1:** every existing feature demonstrably works end-to-end (screenshot → visible in Loot, exfil → download, creds → UI, auth on, services survive reboot). **Ship gate after Phase 2:** a stranger could run the dashboard without asking how anything works.