Fleet Deck 0.5.0
Fleet Deck installs as a Claude Code plugin — there is nothing to download here. Get it with:
claude plugin marketplace add lacion/fleet-deck
claude plugin install fleetdeck@fleetdeckA deep security / reliability / performance / quality audit of the daemon and
board, run as a multi-agent effort with cross-provider adversarial review of
every change. See docs/AUDIT-2026-07.md for the full report.
Security
- Fixed a critical CSRF / cross-site WebSocket hijack: loopback was auto-trusted with no
Origin/Host/Content-Typecheck, so any web page you visited could read the/wssnapshot, drive/ws/term, and POST/api/spawn. State-changing routes and both WS upgrades now enforce anOrigin/Host/Sec-Fetchallowlist plus anapplication/jsonrequirement (this also closes DNS rebinding), without breaking the zero-config loopback board. - Hardened the LAN token: it no longer rides the WebSocket broadcast or gets logged;
fleetd.logand hook-payload capture are now mode0600(capture off by default);remote.urlis restricted tohttps://claude.ai; the mDNS instance name is anonymized.
Fixed
- Node 24 compatibility: the HOME-lock owner check identified fleetd via
/proc/<pid>/comm, which Node 24 renames toMainThread— a second daemon could misread a live owner as a recycled PID, steal the lock, and open its SQLite alongside it. The check now resolves the/proc/<pid>/exesymlink. Caught by the new CI's Node 22/24 matrix on its first run. - Four production spawn-lifecycle bugs (reported over the fleet board after they lost every live terminal):
/clearno longer condemns a live pane; retention verifies a pane via tmux before presuming a silent-but-live agent dead;pane-dead/gonespawns are re-validated and resurrected with hysteresis, andrevive()adopts a live pane instead of 409-deadlocking; mail no longer silently truncates at 500 chars (now bounded at 4000, surrogate-safe, and signalled). - Reliability hardening: worktree removal no longer
rm -rfs uncommitted work without--force; boot reconciliation no longer tombstones the live fleet on a tmux timeout; per-paste unique tmux buffers stop cross-agent mail bleed; plus byte-correct UTF-8 request bodies, WS keepalive and backpressure, bounded DB and caches, and a globalunhandledRejectionhandler.
Changed
- Performance: broadcast coalescing, tiered transcript reads, memoized board and clock context, idle poll backoff, batched PTY output, and a prepared-statement cache.
- Structure:
derive.mjs(2955 lines) was split into a 314-line composition root plus 13 focused modules, andApp.jsx(763 → 433 lines) into hooks plus aHeadercomponent — both verified behavior-preserving. Accessibility: ARIA-legal cards, modal focus traps, and keyboard tile focus.