import SwiftUI @MainActor @Observable final class SpikeLog { var lines: [String] = [] func log(_ line: String) { lines.append(line) } } struct SpikeView: View { @Environment(Store.self) private var store @Environment(SpikeLog.self) private var spike var body: some View { let selection = Binding(get: { store.selectedTaskId ?? "" }, set: { store.focusTask($0) }) VStack(spacing: 0) { HStack { Picker("Task", selection: selection) { Text("None").tag("") ForEach(store.activeTasks(), id: \.task.id) { row in Text(verbatim: "\(row.project.name): \(row.task.title) · \(store.taskState(row.task).label)").tag(row.task.id) } } .frame(width: 420) Text(verbatim: "\(store.me?.displayName ?? "") · \(store.activeTasks().count) active tasks · \(store.inbox.count) inbox · \(store.transcriptLoading() ? "loading" : "\(store.transcript.count) events") · \(store.connected ? "connected" : "reconnecting…")") .foregroundStyle(Palette.muted) Spacer() } .padding(8) Divider() TabView { Tab("Composer", systemImage: "keyboard") { ComposerSpike() } Tab("Transcript", systemImage: "text.alignleft") { TranscriptSpike() .id(store.selectedTaskId) } Tab("Terminal", systemImage: "terminal") { TerminalSpike() .id(store.selectedTaskId) } Tab("Font", systemImage: "textformat") { FontSpike() } Tab("SVG", systemImage: "photo") { SVGSpike() .id(store.selectedTaskId) } } .padding(8) Divider() ScrollView { VStack(alignment: .leading, spacing: 2) { ForEach(Array(spike.lines.enumerated()), id: \.offset) { _, line in Text(line) } } .frame(maxWidth: .infinity, alignment: .leading) .padding(8) } .defaultScrollAnchor(.bottom) .frame(height: 140) } .frame(minWidth: 1000, minHeight: 700) } }