Skip to content

Epic: retro-desktop landing page (folders, app icons, windows) #112

Description

@dev-dull

Vision

Reimagine the post-login landing page (landing/app/templates/index.html) as a retro computer desktop: teams are folders, apps are icons inside them. Double-click a folder to open it; click an app to launch it; right-click an app for a menu with History and Build. Users can open multiple apps at once, each in its own draggable window.

Feasibility verdict: window dressing — no stack changes required

Analysis of the current landing/app confirms the metaphor is a frontend redesign that reuses existing endpoints. Nothing about pods, sessions, routing, or the proxy needs to change:

  • Folders already exist — apps live at apps/{team}/{app-slug}/; catalog.scan_apps() groups by team. Folders = teams.
  • All three actions are already routes (landing/app/templates/index.html:256-258):
    • Launch (click) → GET /run/{team}/{slug} (run pod)
    • Build (right-click) → GET /build/{team}/{slug} (build pod)
    • History (right-click) → GET /versions/{team}/{slug}
  • Concurrency is already in the data modelSessionStore is keyed (user_id, app_slug), so a user can hold multiple simultaneous build sessions for different apps; build pods are uniquely named; run pods are per-(team, app_slug) and already coexist. Nothing enforces one-app-at-a-time.
  • Pages are iframe-embeddable — there are no X-Frame-Options / CSP frame-ancestors headers anywhere in the landing app, so windows can host /run and /build as same-origin iframes. (Build/run pages already nest iframes internally for terminal + preview; 2-deep nesting is fine.)

So this is a real frontend effort (a client-side window manager is heavier than today's server-rendered HTMX catalog), but it is not a change to how the stack operates.

Caveats to handle (not blockers)

  1. Resource cost of concurrent builds — each build pod requests 250m CPU / 256Mi. Many concurrent build windows multiply cluster load. Consider a soft per-user cap, or scope v1 to "launch/view freely, keep active builds modest." Launching (run pods) is cheaper and shared per-app.
  2. Background heartbeat throttlingbuild.html keeps pods alive via JS heartbeats; browsers throttle timers in hidden/background iframes, so a minimized build window could be idle-reaped by the 10-min cleanup (cleanup.py). The window manager should keep heartbeats firing for open-but-inactive windows, or we accept that minimized builds may reap.
  3. iframe contract — the CLAUDE.md rule "absolute links break out of the iframe and load the landing page" still holds; the desktop shell must not be the thing that breaks out, and must preserve relative-link behavior for embedded run/build content.

Sub-issues

Non-goals (v1)

  • No backend/session/pod/proxy changes — if a proposed feature needs one, it's out of scope for this epic.
  • Not necessarily drag-and-drop file management, trash, or a full OS metaphor — just folders, icons, windows, and the context menu.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestuiLanding page / frontend UX

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions