1→import SwiftUI 2→import Charts 3→import UniformTypeIdentifiers 4→ 5→struct MonitoringView: View { 6→ @EnvironmentObject var appState: AppState 7→ @State private var selectedRun: CCRun? 8→ @State private var statusFilter: RunStatus? = nil 9→ @State private var showRealtimeConsumption = false 10→ @State private var showExportSheet = false 11→ 12→ var filteredRuns: [CCRun] { 13→ if let filter = statusFilter { 14→ return appState.recentRuns.filter { $0.status == filter } 15→ } 16→ return appState.recentRuns 17→ } 18→ 19→ @FocusState private var isListFocused: Bool 20→ 21→ var body: some View { 22→ HSplitView { 23→ // Runs List 24→ VStack(spacing: 0) { 25→ // Filter Bar 26→ HStack { 27→ Text("CC Runs") 28→ .font(.headline) 29→ 30→ Spacer() 31→ 32→ // Quick filter buttons 33→ HStack(spacing: 4) { 34→ FilterButton(title: "All", isSelected: statusFilter == nil) { 35→ statusFilter = nil 36→ } 37→ FilterButton(title: "✓", isSelected: statusFilter == .completed, color: .green) { 38→ statusFilter = .completed 39→ } 40→ FilterButton(title: "✗", isSelected: statusFilter == .failed, color: .red) { 41→ statusFilter = .failed 42→ } 43→ } 44→ 45→ Picker("Status", selection: $statusFilter) { 46→ Text("All").tag(nil as RunStatus?) 47→ ForEach([RunStatus.completed, .running, .failed, .pending], id: \.self) { status in 48→ Text(status.rawValue.capitalized).tag(status as RunStatus?) 49→ } 50→ } 51→ .pickerStyle(.menu) 52→ .frame(width: 120) 53→ } 54→ .padding() 55→ 56→ Divider() 57→ 58→ // Runs Table with keyboard navigation 59→ if filteredRuns.isEmpty { 60→ ContentUnavailableView { 61→ Label("No Runs", systemImage: "tray") 62→ } description: { 63→ Text("No CC runs match the filter") 64→ } 65→ } else { 66→ List(selection: $selectedRun) { 67→ ForEach(filteredRuns) { run in 68→ RunRow(run: run) 69→ .tag(run) 70→ } 71→ } 72→ .listStyle(.inset) 73→ .focused($isListFocused) 74→ .onKeyPress(.upArrow) { 75→ navigateRuns(by: -1) 76→ return .handled 77→ } 78→ .onKeyPress(.downArrow) { 79→ navigateRuns(by: 1) 80→ return .handled 81→ } 82→ .onKeyPress(.return) { 83→ // Already selected, could open detail or perform action 84→ return .handled 85→ } 86→ } 87→ } 88→ .frame(minWidth: 400) 89→ 90→ // Run Detail 91→ if let run = selectedRun { 92→ RunDetailView(run: run) 93→ } else { 94→ ContentUnavailableView { 95→ Label("Select a Run", systemImage: "cursorarrow.click") 96→ } description: { 97→ Text("Select a run from the list to view details") 98→ } 99→ } 100→ } 101→ .navigationTitle("CC ROI Monitoring") 102→ .toolbar { 103→ ToolbarItem(placement: .automatic) { 104→ Button { 105→ showRealtimeConsumption = true 106→ } label: { 107→ Label("Live Monitor", systemImage: "waveform.path.ecg") 108→ } 109→ .help("Open real-time consumption monitor") 110→ } 111→ 112→ ToolbarItem(placement: .automatic) { 113→ Button { 114→ Task { 115→ await appState.refreshRecentRuns() 116→ } 117→ } label: { 118→ Image(systemName: "arrow.clockwise") 119→ } 120→ .help("Refresh runs") 121→ } 122→ 123→ ToolbarItem(placement: .automatic) { 124→ Button { 125→ if let url = URL(string: "http://localhost:9001/roi") { 126→ NSWorkspace.shared.open(url) 127→ } 128→ } label: { 129→ Image(systemName: "safari") 130→ } 131→ .help("Open ROI Dashboard in browser") 132→ } 133→ 134→ ToolbarItem(placement: .automatic) { 135→ Menu { 136→ Button { 137→ exportAsJSON() 138→ } label: { 139→ Label("Export as JSON", systemImage: "doc.text") 140→ } 141→ 142→ Button { 143→ exportAsCSV() 144→ } label: { 145→ Label("Export as CSV", systemImage: "tablecells") 146→ } 147→ 148→ Divider() 149→ 150→ Button { 151→ showExportSheet = true 152→ } label: { 153→ Label("Export Summary Report", systemImage: "doc.richtext") 154→ } 155→ } label: { 156→ Image(systemName: "square.and.arrow.up") 157→ } 158→ .help("Export data") 159→ } 160→ 161→ ToolbarItem(placement: .automatic) { 162→ KeyboardHelpButton() 163→ } 164→ } 165→ .sheet(isPresented: $showRealtimeConsumption) { 166→ NavigationStack { 167→ RealtimeConsumptionView() 168→ .frame(minWidth: 750, minHeight: 650) 169→ .toolbar { 170→ ToolbarItem(placement: .cancellationAction) { 171→ Button("Close") { 172→ showRealtimeConsumption = false 173→ } 174→ } 175→ } 176→ } 177→ } 178→ .sheet(isPresented: $showExportSheet) { 179→ ExportSummaryView(runs: filteredRuns, summary: appState.roiSummary, allTime: appState.allTimeStats) 180→ .frame(minWidth: 600, minHeight: 500) 181→ } 182→ .onAppear { 183→ // Focus list on appear 184→ isListFocused = true 185→ } 186→ } 187→ 188→ private func navigateRuns(by offset: Int) { 189→ guard !filteredRuns.isEmpty else { return } 190→ 191→ if let current = selectedRun, 192→ let currentIndex = filteredRuns.firstIndex(where: { $0.id == current.id }) { 193→ let newIndex = max(0, min(filteredRuns.count - 1, currentIndex + offset)) 194→ selectedRun = filteredRuns[newIndex] 195→ } else { 196→ selectedRun = offset > 0 ? filteredRuns.first : filteredRuns.last 197→ } 198→ } 199→ 200→ // MARK: - Export Functions 201→ 202→ private func exportAsJSON() { 203→ let runs = filteredRuns.map { run -> [String: Any] in 204→ [ 205→ "id": run.id, 206→ "prompt": run.prompt, 207→ "source": run.source, 208→ "status": run.status.rawValue, 209→ "model": run.model ?? "unknown", 210→ "inputTokens": run.inputTokens, 211→ "outputTokens": run.outputTokens, 212→ "cacheReadTokens": run.cacheReadTokens, 213→ "costUsd": run.costUsd, 214→ "valueGeneratedUsd": run.valueGeneratedUsd, 215→ "roi": run.roi, 216→ "startedAt": run.startedAt.ISO8601Format(), 217→ "durationMs": run.durationMs ?? 0 218→ ] 219→ } 220→ 221→ do { 222→ let data = try JSONSerialization.data(withJSONObject: runs, options: .prettyPrinted) 223→ saveToFile(data: data, filename: "cc-runs-export.json", fileType: .json) 224→ } catch { 225→ print("Failed to export JSON: \(error)") 226→ } 227→ } 228→ 229→ private func exportAsCSV() { 230→ var csv = "ID,Prompt,Source,Status,Model,Input Tokens,Output Tokens,Cache Tokens,Cost USD,Value USD,ROI %,Started At,Duration\n" 231→ 232→ for run in filteredRuns { 233→ let prompt = run.prompt.replacingOccurrences(of: ",", with: ";").replacingOccurrences(of: "\n", with: " ") 234→ csv += "\"\(run.id)\",\"\(prompt)\",\"\(run.source)\",\"\(run.status.rawValue)\",\"\(run.model ?? "unknown")\",\(run.inputTokens),\(run.outputTokens),\(run.cacheReadTokens),\(run.costUsd),\(run.valueGeneratedUsd),\(run.roi),\"\(run.startedAt.ISO8601Format())\",\(run.durationMs ?? 0)\n" 235→ } 236→ 237→ if let data = csv.data(using: .utf8) { 238→ saveToFile(data: data, filename: "cc-runs-export.csv", fileType: .commaSeparatedText) 239→ } 240→ } 241→ 242→ private func saveToFile(data: Data, filename: String, fileType: UTType) { 243→ let panel = NSSavePanel() 244→ panel.allowedContentTypes = [fileType] 245→ panel.nameFieldStringValue = filename 246→ panel.canCreateDirectories = true 247→ 248→ panel.begin { response in 249→ if response == .OK, let url = panel.url { 250→ do { 251→ try data.write(to: url) 252→ NSWorkspace.shared.activateFileViewerSelecting([url]) 253→ } catch { 254→ print("Failed to save file: \(error)") 255→ } 256→ } 257→ } 258→ } 259→} 260→ 261→// MARK: - Filter Button 262→ 263→struct FilterButton: View { 264→ let title: String 265→ let isSelected: Bool 266→ var color: Color = .secondary 267→ let action: () -> Void 268→ 269→ var body: some View { 270→ Button(action: action) { 271→ Text(title) 272→ .font(.caption) 273→ .padding(.horizontal, 8) 274→ .padding(.vertical, 4) 275→ .background(isSelected ? color.opacity(0.3) : Color.secondary.opacity(0.1)) 276→ .foregroundStyle(isSelected ? color : .secondary) 277→ .clipShape(Capsule()) 278→ } 279→ .buttonStyle(.plain) 280→ } 281→} 282→ 283→// MARK: - Run Row 284→ 285→struct RunRow: View { 286→ let run: CCRun 287→ 288→ var body: some View { 289→ VStack(alignment: .leading, spacing: 6) { 290→ HStack { 291→ Circle() 292→ .fill(statusColor) 293→ .frame(width: 8, height: 8) 294→ 295→ Text(run.prompt) 296→ .font(.subheadline) 297→ .lineLimit(2) 298→ 299→ Spacer() 300→ 301→ Text(run.source) 302→ .font(.caption) 303→ .padding(.horizontal, 6) 304→ .padding(.vertical, 2) 305→ .background(Color.secondary.opacity(0.2)) 306→ .clipShape(Capsule()) 307→ } 308→ 309→ HStack { 310→ Label(run.formattedDuration, systemImage: "clock") 311→ .font(.caption) 312→ .foregroundStyle(.secondary) 313→ 314→ Spacer() 315→ 316→ Text(String(format: "Cost: $%.3f", run.costUsd)) 317→ .font(.caption.monospacedDigit()) 318→ .foregroundStyle(.secondary) 319→ 320→ Text(String(format: "Value: $%.2f", run.valueGeneratedUsd)) 321→ .font(.caption.monospacedDigit()) 322→ .foregroundStyle(run.valueGeneratedUsd > run.costUsd ? .green : .orange) 323→ } 324→ } 325→ .padding(.vertical, 4) 326→ } 327→ 328→ private var statusColor: Color { 329→ switch run.status { 330→ case .completed: return .green 331→ case .running: return .blue 332→ case .failed: return .red 333→ case .pending: return .orange 334→ case .halted: return .gray 335→ } 336→ } 337→} 338→ 339→// MARK: - Run Detail View 340→ 341→struct RunDetailView: View { 342→ let run: CCRun 343→ 344→ var body: some View { 345→ ScrollView { 346→ VStack(alignment: .leading, spacing: 20) { 347→ // Header 348→ VStack(alignment: .leading, spacing: 8) { 349→ HStack { 350→ StatusBadge(status: run.status) 351→ 352→ Spacer() 353→ 354→ if run.valueIsEstimated { 355→ Label("Estimated", systemImage: "questionmark.circle") 356→ .font(.caption) 357→ .foregroundStyle(.orange) 358→ } 359→ } 360→ 361→ Text(run.prompt) 362→ .font(.title3) 363→ 364→ Text("ID: \(run.id)") 365→ .font(.caption.monospaced()) 366→ .foregroundStyle(.secondary) 367→ .textSelection(.enabled) 368→ } 369→ 370→ Divider() 371→ 372→ // Metrics Grid 373→ LazyVGrid(columns: [ 374→ GridItem(.flexible()), 375→ GridItem(.flexible()), 376→ GridItem(.flexible()) 377→ ], spacing: 16) { 378→ MetricCard(title: "Cost", value: String(format: "$%.4f", run.costUsd), icon: "dollarsign.circle", color: .red) 379→ MetricCard(title: "Value", value: String(format: "$%.2f", run.valueGeneratedUsd), icon: "arrow.up.circle", color: .green) 380→ MetricCard(title: "ROI", value: String(format: "%.0f%%", run.roi), icon: "percent", color: run.roi >= 100 ? .green : .orange) 381→ 382→ MetricCard(title: "Input Tokens", value: formatNumber(run.inputTokens), icon: "arrow.down.circle", color: .blue) 383→ MetricCard(title: "Output Tokens", value: formatNumber(run.outputTokens), icon: "arrow.up.circle", color: .purple) 384→ MetricCard(title: "Cache Tokens", value: formatNumber(run.cacheReadTokens), icon: "arrow.triangle.2.circlepath", color: .cyan) 385→ 386→ MetricCard(title: "Duration", value: run.formattedDuration, icon: "clock", color: .secondary) 387→ MetricCard(title: "Source", value: run.source, icon: "app.badge", color: .secondary) 388→ MetricCard(title: "Model", value: run.model ?? "Unknown", icon: "cpu", color: .secondary) 389→ } 390→ 391→ // Tools Used 392→ if let tools = run.toolsUsed, !tools.isEmpty { 393→ GroupBox("Tools Used") { 394→ FlowLayout(spacing: 8) { 395→ ForEach(tools, id: \.self) { tool in 396→ Text(tool) 397→ .font(.caption) 398→ .padding(.horizontal, 8) 399→ .padding(.vertical, 4) 400→ .background(Color.blue.opacity(0.2)) 401→ .clipShape(Capsule()) 402→ } 403→ } 404→ } 405→ } 406→ 407→ // Files Modified 408→ if let files = run.filesModified, !files.isEmpty { 409→ GroupBox("Files Modified (\(files.count))") { 410→ VStack(alignment: .leading, spacing: 4) { 411→ ForEach(files.prefix(10), id: \.self) { file in 412→ Text(file) 413→ .font(.caption.monospaced()) 414→ .lineLimit(1) 415→ } 416→ if files.count > 10 { 417→ Text("... and \(files.count - 10) more") 418→ .font(.caption) 419→ .foregroundStyle(.secondary) 420→ } 421→ } 422→ } 423→ } 424→ 425→ // Error Message 426→ if let error = run.errorMessage { 427→ GroupBox("Error") { 428→ Text(error) 429→ .font(.caption.monospaced()) 430→ .foregroundStyle(.red) 431→ } 432→ } 433→ 434→ // Timestamps 435→ GroupBox("Timeline") { 436→ VStack(alignment: .leading, spacing: 4) { 437→ HStack { 438→ Text("Started:") 439→ .foregroundStyle(.secondary) 440→ Spacer() 441→ Text(run.startedAt.formatted(date: .abbreviated, time: .standard)) 442→ .font(.caption.monospaced()) 443→ } 444→ 445→ if let completed = run.completedAt { 446→ HStack { 447→ Text("Completed:") 448→ .foregroundStyle(.secondary) 449→ Spacer() 450→ Text(completed.formatted(date: .abbreviated, time: .standard)) 451→ .font(.caption.monospaced()) 452→ } 453→ } 454→ } 455→ .font(.caption) 456→ } 457→ } 458→ .padding() 459→ } 460→ .frame(minWidth: 400) 461→ } 462→ 463→ private func formatNumber(_ n: Int) -> String { 464→ if n >= 1_000_000 { 465→ return String(format: "%.1fM", Double(n) / 1_000_000) 466→ } else if n >= 1_000 { 467→ return String(format: "%.1fK", Double(n) / 1_000) 468→ } 469→ return "\(n)" 470→ } 471→} 472→ 473→// MARK: - Supporting Views 474→ 475→struct StatusBadge: View { 476→ let status: RunStatus 477→ 478→ var body: some View { 479→ Text(status.rawValue.capitalized) 480→ .font(.caption.bold()) 481→ .padding(.horizontal, 8) 482→ .padding(.vertical, 4) 483→ .background(backgroundColor) 484→ .foregroundStyle(.white) 485→ .clipShape(Capsule()) 486→ } 487→ 488→ private var backgroundColor: Color { 489→ switch status { 490→ case .completed: return .green 491→ case .running: return .blue 492→ case .failed: return .red 493→ case .pending: return .orange 494→ case .halted: return .gray 495→ } 496→ } 497→} 498→ 499→struct MetricCard: View { 500→ let title: String 501→ let value: String 502→ let icon: String 503→ let color: Color 504→ 505→ var body: some View { 506→ VStack(alignment: .leading, spacing: 4) { 507→ HStack { 508→ Image(systemName: icon) 509→ .foregroundStyle(color) 510→ Text(title) 511→ .foregroundStyle(.secondary) 512→ } 513→ .font(.caption) 514→ 515→ Text(value) 516→ .font(.headline.monospacedDigit()) 517→ } 518→ .frame(maxWidth: .infinity, alignment: .leading) 519→ .padding() 520→ .background(Color(nsColor: .controlBackgroundColor)) 521→ .clipShape(RoundedRectangle(cornerRadius: 8)) 522→ } 523→} 524→ 525→struct FlowLayout: Layout { 526→ var spacing: CGFloat = 8 527→ 528→ func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize { 529→ let result = FlowResult(in: proposal.width ?? 0, subviews: subviews, spacing: spacing) 530→ return result.size 531→ } 532→ 533→ func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) { 534→ let result = FlowResult(in: bounds.width, subviews: subviews, spacing: spacing) 535→ for (index, frame) in result.frames.enumerated() { 536→ subviews[index].place(at: CGPoint(x: bounds.minX + frame.origin.x, y: bounds.minY + frame.origin.y), proposal: ProposedViewSize(frame.size)) 537→ } 538→ } 539→ 540→ struct FlowResult { 541→ var size: CGSize = .zero 542→ var frames: [CGRect] = [] 543→ 544→ init(in maxWidth: CGFloat, subviews: Subviews, spacing: CGFloat) { 545→ var x: CGFloat = 0 546→ var y: CGFloat = 0 547→ var rowHeight: CGFloat = 0 548→ 549→ for subview in subviews { 550→ let size = subview.sizeThatFits(.unspecified) 551→ if x + size.width > maxWidth, x > 0 { 552→ x = 0 553→ y += rowHeight + spacing 554→ rowHeight = 0 555→ } 556→ frames.append(CGRect(origin: CGPoint(x: x, y: y), size: size)) 557→ x += size.width + spacing 558→ rowHeight = max(rowHeight, size.height) 559→ } 560→ 561→ self.size = CGSize(width: maxWidth, height: y + rowHeight) 562→ } 563→ } 564→} 565→ 566→// MARK: - Export Summary View 567→ 568→struct ExportSummaryView: View { 569→ @Environment(\.dismiss) var dismiss 570→ let runs: [CCRun] 571→ let summary: ROISummary? 572→ let allTime: AllTimeStats? 573→ 574→ var body: some View { 575→ NavigationStack { 576→ ScrollView { 577→ VStack(alignment: .leading, spacing: 20) { 578→ // Header 579→ VStack(alignment: .leading, spacing: 4) { 580→ Text("CC ROI Summary Report") 581→ .font(.title.bold()) 582→ Text("Generated: \(Date().formatted(date: .long, time: .shortened))") 583→ .font(.caption) 584→ .foregroundStyle(.secondary) 585→ } 586→ 587→ Divider() 588→ 589→ // Today's Summary 590→ if let summary = summary { 591→ GroupBox("Today's Performance") { 592→ LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())], spacing: 12) { 593→ SummaryMetric(title: "Total Cost", value: String(format: "$%.2f", summary.totalCost), color: .red) 594→ SummaryMetric(title: "Total Value", value: String(format: "$%.2f", summary.totalValue), color: .green) 595→ SummaryMetric(title: "Profit", value: String(format: "$%.2f", summary.profit), color: summary.profit >= 0 ? .green : .red) 596→ SummaryMetric(title: "ROI", value: String(format: "%.0f%%", summary.roiPercent), color: .blue) 597→ SummaryMetric(title: "Runs", value: "\(summary.runCount)", color: .purple) 598→ SummaryMetric(title: "Success Rate", value: String(format: "%.0f%%", summary.successRate), color: .orange) 599→ } 600→ } 601→ } 602→ 603→ // All-Time Stats 604→ if let allTime = allTime { 605→ GroupBox("All-Time Statistics") { 606→ LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())], spacing: 12) { 607→ SummaryMetric(title: "Total Cost", value: String(format: "$%.2f", allTime.totalCost), color: .red) 608→ SummaryMetric(title: "Total Value", value: String(format: "$%.2f", allTime.totalValue), color: .green) 609→ SummaryMetric(title: "Total Profit", value: String(format: "$%.2f", allTime.totalProfit), color: allTime.totalProfit >= 0 ? .green : .red) 610→ SummaryMetric(title: "Avg ROI", value: String(format: "%.0f%%", allTime.averageROI), color: .blue) 611→ SummaryMetric(title: "Total Runs", value: "\(allTime.totalRuns)", color: .purple) 612→ SummaryMetric(title: "Success Rate", value: String(format: "%.0f%%", allTime.successRate), color: .orange) 613→ } 614→ } 615→ } 616→ 617→ // Recent Runs 618→ GroupBox("Recent Runs (\(runs.count))") { 619→ if runs.isEmpty { 620→ Text("No runs to display") 621→ .font(.caption) 622→ .foregroundStyle(.secondary) 623→ .frame(maxWidth: .infinity) 624→ .padding() 625→ } else { 626→ VStack(spacing: 8) { 627→ ForEach(runs.prefix(10)) { run in 628→ HStack { 629→ Circle() 630→ .fill(run.status == .completed ? .green : (run.status == .failed ? .red : .orange)) 631→ .frame(width: 8, height: 8) 632→ 633→ Text(run.prompt) 634→ .font(.caption) 635→ .lineLimit(1) 636→ 637→ Spacer() 638→ 639→ Text(String(format: "$%.3f", run.costUsd)) 640→ .font(.caption.monospacedDigit()) 641→ .foregroundStyle(.secondary) 642→ 643→ Text(String(format: "→ $%.2f", run.valueGeneratedUsd)) 644→ .font(.caption.monospacedDigit()) 645→ .foregroundStyle(.green) 646→ } 647→ } 648→ 649→ if runs.count > 10 { 650→ Text("... and \(runs.count - 10) more") 651→ .font(.caption) 652→ .foregroundStyle(.tertiary) 653→ } 654→ } 655→ } 656→ } 657→ 658→ // Token Summary 659→ GroupBox("Token Usage") { 660→ let totalInput = runs.reduce(0) { $0 + $1.inputTokens } 661→ let totalOutput = runs.reduce(0) { $0 + $1.outputTokens } 662→ let totalCache = runs.reduce(0) { $0 + $1.cacheReadTokens } 663→ 664→ HStack(spacing: 20) { 665→ TokenSummary(label: "Input", count: totalInput, color: .blue) 666→ TokenSummary(label: "Output", count: totalOutput, color: .purple) 667→ TokenSummary(label: "Cache", count: totalCache, color: .cyan) 668→ } 669→ } 670→ } 671→ .padding() 672→ } 673→ .navigationTitle("Export Summary") 674→ .toolbar { 675→ ToolbarItem(placement: .cancellationAction) { 676→ Button("Close") { 677→ dismiss() 678→ } 679→ } 680→ 681→ ToolbarItem(placement: .confirmationAction) { 682→ Button("Copy to Clipboard") { 683→ copyReportToClipboard() 684→ } 685→ } 686→ } 687→ } 688→ } 689→ 690→ private func copyReportToClipboard() { 691→ var report = """ 692→ CC ROI Summary Report 693→ Generated: \(Date().formatted(date: .long, time: .shortened)) 694→ 695→ """ 696→ 697→ if let summary = summary { 698→ report += """ 699→ 700→ TODAY'S PERFORMANCE 701→ ------------------- 702→ Total Cost: $\(String(format: "%.2f", summary.totalCost)) 703→ Total Value: $\(String(format: "%.2f", summary.totalValue)) 704→ Profit: $\(String(format: "%.2f", summary.profit)) 705→ ROI: \(String(format: "%.0f%%", summary.roiPercent)) 706→ Runs: \(summary.runCount) 707→ Success Rate: \(String(format: "%.0f%%", summary.successRate)) 708→ 709→ """ 710→ } 711→ 712→ if let allTime = allTime { 713→ report += """ 714→ 715→ ALL-TIME STATISTICS 716→ ------------------- 717→ Total Cost: $\(String(format: "%.2f", allTime.totalCost)) 718→ Total Value: $\(String(format: "%.2f", allTime.totalValue)) 719→ Total Profit: $\(String(format: "%.2f", allTime.totalProfit)) 720→ Avg ROI: \(String(format: "%.0f%%", allTime.averageROI)) 721→ Total Runs: \(allTime.totalRuns) 722→ Success Rate: \(String(format: "%.0f%%", allTime.successRate)) 723→ 724→ """ 725→ } 726→ 727→ let totalInput = runs.reduce(0) { $0 + $1.inputTokens } 728→ let totalOutput = runs.reduce(0) { $0 + $1.outputTokens } 729→ let totalCache = runs.reduce(0) { $0 + $1.cacheReadTokens } 730→ 731→ report += """ 732→ 733→ TOKEN USAGE 734→ ----------- 735→ Input Tokens: \(formatNumber(totalInput)) 736→ Output Tokens: \(formatNumber(totalOutput)) 737→ Cache Tokens: \(formatNumber(totalCache)) 738→ 739→ RECENT RUNS (\(runs.count)) 740→ ------------ 741→ """ 742→ 743→ for run in runs.prefix(10) { 744→ report += "\n• \(run.prompt.prefix(50))... | $\(String(format: "%.3f", run.costUsd)) → $\(String(format: "%.2f", run.valueGeneratedUsd))" 745→ } 746→ 747→ NSPasteboard.general.clearContents() 748→ NSPasteboard.general.setString(report, forType: .string) 749→ } 750→ 751→ private func formatNumber(_ n: Int) -> String { 752→ if n >= 1_000_000 { 753→ return String(format: "%.2fM", Double(n) / 1_000_000) 754→ } else if n >= 1_000 { 755→ return String(format: "%.1fK", Double(n) / 1_000) 756→ } 757→ return "\(n)" 758→ } 759→} 760→ 761→struct SummaryMetric: View { 762→ let title: String 763→ let value: String 764→ let color: Color 765→ 766→ var body: some View { 767→ VStack(alignment: .leading, spacing: 4) { 768→ Text(title) 769→ .font(.caption) 770→ .foregroundStyle(.secondary) 771→ Text(value) 772→ .font(.headline.monospacedDigit()) 773→ .foregroundStyle(color) 774→ } 775→ .frame(maxWidth: .infinity, alignment: .leading) 776→ } 777→} 778→ 779→struct TokenSummary: View { 780→ let label: String 781→ let count: Int 782→ let color: Color 783→ 784→ var body: some View { 785→ VStack(spacing: 4) { 786→ Text(label) 787→ .font(.caption) 788→ .foregroundStyle(.secondary) 789→ Text(formatCount(count)) 790→ .font(.title3.bold().monospacedDigit()) 791→ .foregroundStyle(color) 792→ } 793→ .frame(maxWidth: .infinity) 794→ } 795→ 796→ private func formatCount(_ n: Int) -> String { 797→ if n >= 1_000_000 { 798→ return String(format: "%.2fM", Double(n) / 1_000_000) 799→ } else if n >= 1_000 { 800→ return String(format: "%.1fK", Double(n) / 1_000) 801→ } 802→ return "\(n)" 803→ } 804→} 805→ 806→#Preview { 807→ MonitoringView() 808→ .environmentObject(AppState()) 809→ .frame(width: 1000, height: 700) 810→} 811→ Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.