ai-dispatch 10.40.0

Multi-AI CLI team orchestrator
// Console shell — assembles HUD, gauges, rail, center tabs, brief band.
// Exports: ConsoleShellView.

import SwiftUI

struct ConsoleShellView: View {
    @Environment(\.theme) private var theme
    @Bindable var store: FleetStore
    @Bindable var themeManager: ThemeManager

    var body: some View {
        ConsoleLayoutReader { layout in
            ZStack {
                VStack(spacing: 0) {
                    HUDBarView(
                        snapshot: store.snapshot,
                        xpState: store.xpState,
                        commanderName: store.commanderName,
                        selectedTab: tabBinding,
                        onToggleRail: { store.showLeftRail.toggle() }
                    )
                    GaugeStripView(summary: store.snapshot.summary)
                        .padding(.horizontal, theme.spacing.md)
                    HStack(spacing: 0) {
                        if layout != .compact {
                            LeftRailView(
                                sectors: store.snapshot.sectors,
                                selectedSectorID: sectorBinding
                            )
                            .frame(width: layout.leftRailWidth)
                            .frame(maxHeight: .infinity, alignment: .top)
                            .layoutPriority(1)
                        }
                        centerContent
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                    }
                    .frame(maxHeight: .infinity)
                    .frame(minHeight: 0)
                    if layout.showsBottomBrief {
                        MissionBriefView(
                            snapshot: store.snapshot,
                            selectedMissionID: store.selectedMissionID,
                            detail: store.missionDetail,
                            actionMessage: store.actionMessage,
                            onAction: { action in
                                Task { await store.performAction(action) }
                            }
                        )
                        .frame(height: 268)
                    }
                }
                ScreenFrame()
                ToastStack(toasts: store.toasts)
            }
            .background { ConsoleBackground() }
            .sheet(item: $store.documentPayload) { payload in
                TextDocumentSheet(payload: payload)
                    .environment(\.theme, theme)
            }
            .sheet(isPresented: $store.showLeftRail) {
                if layout == .compact {
                    NavigationStack {
                        LeftRailView(
                            sectors: store.snapshot.sectors,
                            selectedSectorID: sectorBinding
                        )
                        .navigationTitle("Tactical Scan")
                    }
                }
            }
        }
    }

    private var tabBinding: Binding<CenterTab> {
        Binding(
            get: { store.selectedTab },
            set: { store.persistTab($0) }
        )
    }

    private var sectorBinding: Binding<String?> {
        Binding(
            get: { store.selectedSectorID },
            set: { store.selectSector($0) }
        )
    }

    @ViewBuilder
    private var centerContent: some View {
        switch store.selectedTab {
        case .fleetLog:
            FleetLogView(
                sectors: store.snapshot.sectors,
                selectedMissionID: missionBinding
            )
        case .hangar:
            if let sector = store.selectedSector {
                HangarView(sector: sector, selectedMissionID: missionBinding)
            } else if let first = store.snapshot.sectors.first {
                HangarView(sector: first, selectedMissionID: missionBinding)
            } else {
                MonoLabel(text: "no sectors", color: theme.ink3)
                    .padding()
            }
        case .cargo:
            CargoView(
                sectors: store.snapshot.sectors,
                selectedMissionID: missionBinding
            )
        }
    }

    private var missionBinding: Binding<MissionID?> {
        Binding(
            get: { store.selectedMissionID },
            set: { store.selectMission($0) }
        )
    }
}