Part 3 of 3 for the "fail fast + comprehensive logs" UX. Platform PR
#1168 and controlplane #181 ship the server-side; this PR surfaces the
data in the canvas.
Two changes:
1. DetailsTab renders `last_sample_error` in a dedicated Error section
when the workspace is failed (or degraded with an error). Before,
the only trace of why a workspace failed was a generic banner —
users had to click "View Logs", which opened the terminal tab (the
post-boot log, empty on a runtime crash). Now the actual Python
traceback is inline. A "View console output" button in the same
section opens the full serial console in a modal.
2. New ConsoleModal component. Fetches GET /workspaces/:id/console
(platform → CP → ec2:GetConsoleOutput). Portal-rendered above the
canvas with Copy / Close / Esc handlers. Renders a friendly message
on 501 (self-hosted deploys without CP) and 404 (instance
terminated).
3. ProvisioningTimeout's "View Logs" button now opens the console
modal instead of the (usually empty) terminal tab — when a
workspace is stuck in provisioning, the cloud-init + user-data
trace is what the user actually needs.
Tests cover the closed-state no-fetch, happy-path fetch, 501/404
messaging, and Close/Escape wiring.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>