     1→import Foundation
     2→import Combine
     3→import AppKit
     4→import SwiftUI
     5→
     6→// MARK: - Consumption Tracker
     7→
     8→/// Monitors Claude Code CLI processes in real-time and tracks token consumption
     9→@MainActor
    10→final class ConsumptionTracker: ObservableObject {
    11→    static let shared = ConsumptionTracker()
    12→
    13→    // MARK: - Published State
    14→
    15→    // Session metrics
    16→    @Published var sessionCost: Double = 0
    17→    @Published var sessionInputTokens: Int = 0
    18→    @Published var sessionOutputTokens: Int = 0
    19→    @Published var sessionCacheTokens: Int = 0
    20→    @Published var sessionStartTime: Date = Date()
    21→
    22→    // Rates
    23→    @Published var costPerHour: Double = 0
    24→    @Published var costPerMinute: Double = 0
    25→    @Published var inputTokensPerMinute: Double = 0
    26→    @Published var outputTokensPerMinute: Double = 0
    27→    @Published var cacheTokensPerMinute: Double = 0
    28→    @Published var costTrend: Double = 0
    29→
    30→    // Process monitoring
    31→    @Published var isMonitoring: Bool = false
    32→    @Published var isPaused: Bool = false
    33→    @Published var activeProcesses: [ClaudeProcess] = []
    34→    @Published var activeRun: CCRun?
    35→
    36→    // History
    37→    @Published var consumptionHistory: [ConsumptionDataPoint] = []
    38→    @Published var recentActivities: [ConsumptionActivity] = []
    39→
    40→    // Live session (real-time from cc-live-tracker.py)
    41→    @Published var liveSessionId: String?
    42→    @Published var liveSessionActive: Bool = false
    43→    @Published var liveSessionCost: Double = 0
    44→    @Published var liveSessionDurationSeconds: Double = 0
    45→
    46→    // MARK: - Private Properties
    47→
    48→    private var monitoringTask: Task<Void, Never>?
    49→    private var liveSessionTask: Task<Void, Never>?
    50→    private var rateCalculationTimer: Timer?
    51→    private var historyTimer: Timer?
    52→    private var cancellables = Set<AnyCancellable>()
    53→
    54→    private let ccService = CCTrackingService()
    55→    private var lastCostSnapshot: Double = 0
    56→    private var lastSnapshotTime: Date = Date()
    57→    private var lastLiveSessionUpdate: Date?
    58→
    59→    // Token pricing (Claude Opus 4.5)
    60→    private let inputTokenPrice: Double = 15.0 / 1_000_000  // $15 per 1M
    61→    private let outputTokenPrice: Double = 75.0 / 1_000_000 // $75 per 1M
    62→    private let cacheTokenPrice: Double = 1.875 / 1_000_000 // $1.875 per 1M (cache read)
    63→
    64→    // MARK: - Initialization
    65→
    66→    private init() {
    67→        startMonitoring()
    68→        startRateCalculation()
    69→        startHistoryTracking()
    70→        startLiveSessionMonitoring()
    71→    }
    72→
    73→    // Note: deinit cannot call @MainActor methods directly
    74→    // Cleanup is handled when the app terminates
    75→
    76→    // MARK: - Public Methods
    77→
    78→    var sessionDuration: String {
    79→        let interval = Date().timeIntervalSince(sessionStartTime)
    80→        let hours = Int(interval) / 3600
    81→        let minutes = (Int(interval) % 3600) / 60
    82→        let seconds = Int(interval) % 60
    83→
    84→        if hours > 0 {
    85→            return String(format: "%dh %dm %ds", hours, minutes, seconds)
    86→        } else if minutes > 0 {
    87→            return String(format: "%dm %ds", minutes, seconds)
    88→        }
    89→        return String(format: "%ds", seconds)
    90→    }
    91→
    92→    func resetSession() {
    93→        sessionCost = 0
    94→        sessionInputTokens = 0
    95→        sessionOutputTokens = 0
    96→        sessionCacheTokens = 0
    97→        sessionStartTime = Date()
    98→        costPerHour = 0
    99→        costPerMinute = 0
   100→        inputTokensPerMinute = 0
   101→        outputTokensPerMinute = 0
   102→        cacheTokensPerMinute = 0
   103→        costTrend = 0
   104→        consumptionHistory.removeAll()
   105→        recentActivities.removeAll()
   106→        lastCostSnapshot = 0
   107→        lastSnapshotTime = Date()
   108→
   109→        addActivity(.info, "Session reset")
   110→    }
   111→
   112→    func startMonitoring() {
   113→        guard !isMonitoring else { return }
   114→        isMonitoring = true
   115→
   116→        monitoringTask = Task {
   117→            await monitorClaudeProcesses()
   118→        }
   119→
   120→        addActivity(.info, "Monitoring started")
   121→    }
   122→
   123→    func stopMonitoring() {
   124→        isMonitoring = false
   125→        monitoringTask?.cancel()
   126→        monitoringTask = nil
   127→        rateCalculationTimer?.invalidate()
   128→        historyTimer?.invalidate()
   129→
   130→        addActivity(.info, "Monitoring stopped")
   131→    }
   132→
   133→    // MARK: - Process Monitoring
   134→
   135→    private func monitorClaudeProcesses() async {
   136→        while isMonitoring && !Task.isCancelled {
   137→            if !isPaused {
   138→                await detectClaudeProcesses()
   139→                await fetchLatestConsumption()
   140→            }
   141→
   142→            try? await Task.sleep(for: .seconds(2))
   143→        }
   144→    }
   145→
   146→    private func detectClaudeProcesses() async {
   147→        // Find claude processes using pgrep
   148→        let process = Process()
   149→        process.executableURL = URL(fileURLWithPath: "/usr/bin/pgrep")
   150→        process.arguments = ["-f", "claude"]
   151→
   152→        let outputPipe = Pipe()
   153→        process.standardOutput = outputPipe
   154→
   155→        do {
   156→            try process.run()
   157→            process.waitUntilExit()
   158→
   159→            let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
   160→            let outputString = String(data: outputData, encoding: .utf8) ?? ""
   161→
   162→            let pids = outputString.components(separatedBy: .newlines)
   163→                .compactMap { Int($0.trimmingCharacters(in: .whitespaces)) }
   164→
   165→            // Get process details for each PID
   166→            var processes: [ClaudeProcess] = []
   167→
   168→            for pid in pids {
   169→                if let processInfo = await getProcessInfo(pid: pid) {
   170→                    processes.append(processInfo)
   171→                }
   172→            }
   173→
   174→            // Update active processes
   175→            let oldCount = activeProcesses.count
   176→            activeProcesses = processes
   177→
   178→            if processes.count != oldCount {
   179→                if processes.count > oldCount {
   180→                    addActivity(.process, "Claude Code process detected (PID: \(processes.last?.pid ?? 0))")
   181→                } else {
   182→                    addActivity(.process, "Claude Code process ended")
   183→                }
   184→            }
   185→
   186→        } catch {
   187→            print("Error detecting claude processes: \(error)")
   188→        }
   189→    }
   190→
   191→    private func getProcessInfo(pid: Int) async -> ClaudeProcess? {
   192→        // Get process command line
   193→        let process = Process()
   194→        process.executableURL = URL(fileURLWithPath: "/bin/ps")
   195→        process.arguments = ["-p", "\(pid)", "-o", "command=", "-o", "etime=", "-o", "%cpu=", "-o", "%mem="]
   196→
   197→        let outputPipe = Pipe()
   198→        process.standardOutput = outputPipe
   199→
   200→        do {
   201→            try process.run()
   202→            process.waitUntilExit()
   203→
   204→            let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
   205→            let outputString = String(data: outputData, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
   206→
   207→            guard !outputString.isEmpty else { return nil }
   208→
   209→            // Parse output
   210→            let components = outputString.components(separatedBy: .whitespaces).filter { !$0.isEmpty }
   211→            guard components.count >= 1 else { return nil }
   212→
   213→            // Check if it's actually a claude process
   214→            let command = components.first ?? ""
   215→            guard command.contains("claude") || command.contains("node") else { return nil }
   216→
   217→            return ClaudeProcess(
   218→                pid: pid,
   219→                command: command,
   220→                startTime: Date(), // Would need to parse etime properly
   221→                cpuUsage: Double(components.last ?? "0") ?? 0
   222→            )
   223→
   224→        } catch {
   225→            return nil
   226→        }
   227→    }
   228→
   229→    // MARK: - Consumption Fetching
   230→
   231→    private func fetchLatestConsumption() async {
   232→        do {
   233→            // Fetch latest ROI summary from API
   234→            let summary = try await ccService.getROISummary()
   235→
   236→            // Calculate delta from last fetch
   237→            let previousCost = sessionCost
   238→            let newTotalCost = summary.totalCost
   239→
   240→            // Fetch recent runs to aggregate token data
   241→            let runs = try await ccService.getRecentRuns(limit: 50)
   242→
   243→            // Aggregate tokens from today's runs
   244→            var totalInput = 0
   245→            var totalOutput = 0
   246→            var totalCache = 0
   247→
   248→            let calendar = Calendar.current
   249→            let today = calendar.startOfDay(for: Date())
   250→
   251→            for run in runs {
   252→                if calendar.isDate(run.startedAt, inSameDayAs: today) {
   253→                    totalInput += run.inputTokens
   254→                    totalOutput += run.outputTokens
   255→                    totalCache += run.cacheReadTokens
   256→                }
   257→            }
   258→
   259→            // Update session metrics based on today's data
   260→            sessionCost = newTotalCost
   261→            sessionInputTokens = totalInput
   262→            sessionOutputTokens = totalOutput
   263→            sessionCacheTokens = totalCache
   264→
   265→            // Track cost trend
   266→            if previousCost > 0 {
   267→                let costDelta = newTotalCost - previousCost
   268→                if costDelta > 0 {
   269→                    addActivity(.cost, "Cost increased", cost: costDelta)
   270→                }
   271→            }
   272→
   273→            // Check for active run
   274→            if let latestRun = runs.first, latestRun.status == .running {
   275→                activeRun = latestRun
   276→            } else {
   277→                activeRun = nil
   278→            }
   279→
   280→        } catch {
   281→            print("Error fetching consumption: \(error)")
   282→        }
   283→    }
   284→
   285→    // MARK: - Rate Calculation
   286→
   287→    private func startRateCalculation() {
   288→        rateCalculationTimer = Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { [weak self] _ in
   289→            Task { @MainActor in
   290→                self?.calculateRates()
   291→            }
   292→        }
   293→    }
   294→
   295→    private func calculateRates() {
   296→        let now = Date()
   297→        let elapsed = now.timeIntervalSince(lastSnapshotTime)
   298→
   299→        guard elapsed > 0 else { return }
   300→
   301→        // Calculate cost rate
   302→        let costDelta = sessionCost - lastCostSnapshot
   303→        costPerMinute = (costDelta / elapsed) * 60
   304→        costPerHour = costPerMinute * 60
   305→
   306→        // Calculate token rates
   307→        let sessionElapsed = now.timeIntervalSince(sessionStartTime)
   308→        if sessionElapsed > 0 {
   309→            inputTokensPerMinute = Double(sessionInputTokens) / (sessionElapsed / 60)
   310→            outputTokensPerMinute = Double(sessionOutputTokens) / (sessionElapsed / 60)
   311→            cacheTokensPerMinute = Double(sessionCacheTokens) / (sessionElapsed / 60)
   312→        }
   313→
   314→        // Calculate trend (% change from last period)
   315→        if lastCostSnapshot > 0 {
   316→            costTrend = ((sessionCost - lastCostSnapshot) / lastCostSnapshot) * 100
   317→        }
   318→
   319→        // Update snapshot
   320→        lastCostSnapshot = sessionCost
   321→        lastSnapshotTime = now
   322→    }
   323→
   324→    // MARK: - History Tracking
   325→
   326→    private func startHistoryTracking() {
   327→        historyTimer = Timer.scheduledTimer(withTimeInterval: 30, repeats: true) { [weak self] _ in
   328→            Task { @MainActor in
   329→                self?.recordHistoryPoint()
   330→            }
   331→        }
   332→
   333→        // Record initial point
   334→        recordHistoryPoint()
   335→    }
   336→
   337→    private func recordHistoryPoint() {
   338→        let point = ConsumptionDataPoint(
   339→            timestamp: Date(),
   340→            cumulativeCost: sessionCost,
   341→            inputTokens: sessionInputTokens,
   342→            outputTokens: sessionOutputTokens,
   343→            cacheTokens: sessionCacheTokens
   344→        )
   345→
   346→        consumptionHistory.append(point)
   347→
   348→        // Keep last 2 hours of data (240 points at 30s intervals)
   349→        if consumptionHistory.count > 240 {
   350→            consumptionHistory.removeFirst()
   351→        }
   352→    }
   353→
   354→    // MARK: - Live Session Monitoring
   355→
   356→    private func startLiveSessionMonitoring() {
   357→        liveSessionTask = Task {
   358→            await monitorLiveSession()
   359→        }
   360→    }
   361→
   362→    private func monitorLiveSession() async {
   363→        while !Task.isCancelled {
   364→            if !isPaused {
   365→                await fetchLiveSession()
   366→            }
   367→            try? await Task.sleep(for: .seconds(1)) // Faster polling for live data
   368→        }
   369→    }
   370→
   371→    private func fetchLiveSession() async {
   372→        guard let url = URL(string: "http://localhost:9001/api/cc/session/current") else { return }
   373→
   374→        do {
   375→            let (data, response) = try await URLSession.shared.data(from: url)
   376→
   377→            guard let httpResponse = response as? HTTPURLResponse,
   378→                  httpResponse.statusCode == 200 else {
   379→                liveSessionActive = false
   380→                return
   381→            }
   382→
   383→            let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
   384→
   385→            if let active = json?["active"] as? Bool, active {
   386→                // Live session is active
   387→                let sessionId = json?["session_id"] as? String
   388→                let cost = json?["cumulative_cost"] as? Double ?? 0
   389→                let duration = json?["duration_seconds"] as? Double ?? 0
   390→                let costRate = json?["cost_rate_per_hour"] as? Double ?? 0
   391→                let tokens = json?["cumulative_tokens"] as? [String: Any]
   392→
   393→                // Update live session state
   394→                if liveSessionId != sessionId {
   395→                    // New session detected
   396→                    addActivity(.process, "Live session started: \(sessionId ?? "unknown")")
   397→                }
   398→
   399→                liveSessionId = sessionId
   400→                liveSessionActive = true
   401→                liveSessionCost = cost
   402→                liveSessionDurationSeconds = duration
   403→
   404→                // Update main metrics from live session
   405→                if let tokens = tokens {
   406→                    let input = tokens["input"] as? Int ?? 0
   407→                    let output = tokens["output"] as? Int ?? 0
   408→                    let cacheRead = tokens["cacheRead"] as? Int ?? 0
   409→
   410→                    // Update session tokens if live data is newer
   411→                    if input > sessionInputTokens || output > sessionOutputTokens {
   412→                        sessionInputTokens = input
   413→                        sessionOutputTokens = output
   414→                        sessionCacheTokens = cacheRead
   415→                    }
   416→                }
   417→
   418→                // Update cost rate from live session
   419→                if costRate > 0 {
   420→                    costPerHour = costRate
   421→                    costPerMinute = costRate / 60
   422→                }
   423→
   424→                // Update session cost if live is higher
   425→                if cost > sessionCost {
   426→                    let costDelta = cost - sessionCost
   427→                    sessionCost = cost
   428→                    if costDelta > 0.0001 {
   429→                        addActivity(.cost, "Live cost update", cost: costDelta)
   430→                    }
   431→                }
   432→
   433→                lastLiveSessionUpdate = Date()
   434→
   435→            } else {
   436→                // No active live session
   437→                if liveSessionActive {
   438→                    addActivity(.process, "Live session ended")
   439→                }
   440→                liveSessionActive = false
   441→                liveSessionId = nil
   442→            }
   443→
   444→        } catch {
   445→            // API not available or error
   446→            if liveSessionActive {
   447→                liveSessionActive = false
   448→            }
   449→        }
   450→    }
   451→
   452→    // MARK: - Activity Logging
   453→
   454→    private func addActivity(_ type: ConsumptionActivity.ActivityType, _ description: String, cost: Double? = nil) {
   455→        let activity = ConsumptionActivity(
   456→            type: type,
   457→            description: description,
   458→            timestamp: Date(),
   459→            cost: cost
   460→        )
   461→
   462→        recentActivities.insert(activity, at: 0)
   463→
   464→        // Keep last 50 activities
   465→        if recentActivities.count > 50 {
   466→            recentActivities.removeLast()
   467→        }
   468→    }
   469→}
   470→
   471→// MARK: - Supporting Types
   472→
   473→struct ClaudeProcess: Identifiable {
   474→    let id = UUID()
   475→    let pid: Int
   476→    let command: String
   477→    let startTime: Date
   478→    let cpuUsage: Double
   479→}
   480→
   481→struct ConsumptionDataPoint: Identifiable {
   482→    let id = UUID()
   483→    let timestamp: Date
   484→    let cumulativeCost: Double
   485→    let inputTokens: Int
   486→    let outputTokens: Int
   487→    let cacheTokens: Int
   488→}
   489→
   490→struct ConsumptionActivity: Identifiable {
   491→    let id = UUID()
   492→    let type: ActivityType
   493→    let description: String
   494→    let timestamp: Date
   495→    let cost: Double?
   496→
   497→    enum ActivityType {
   498→        case info
   499→        case cost
   500→        case tokens
   501→        case process
   502→        case warning
   503→        case error
   504→
   505→        var color: Color {
   506→            switch self {
   507→            case .info: return .blue
   508→            case .cost: return .green
   509→            case .tokens: return .purple
   510→            case .process: return .orange
   511→            case .warning: return .yellow
   512→            case .error: return .red
   513→            }
   514→        }
   515→    }
   516→}
   517→

<system-reminder>
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.
</system-reminder>

import Foundation
import Combine
import AppKit
import SwiftUI

// MARK: - Consumption Tracker

/// Monitors Claude Code CLI processes in real-time and tracks token consumption
@MainActor
final class ConsumptionTracker: ObservableObject {
    static let shared = ConsumptionTracker()

    // MARK: - Published State

    // Session metrics
    @Published var sessionCost: Double = 0
    @Published var sessionInputTokens: Int = 0
    @Published var sessionOutputTokens: Int = 0
    @Published var sessionCacheTokens: Int = 0
    @Published var sessionStartTime: Date = Date()

    // Rates
    @Published var costPerHour: Double = 0
    @Published var costPerMinute: Double = 0
    @Published var inputTokensPerMinute: Double = 0
    @Published var outputTokensPerMinute: Double = 0
    @Published var cacheTokensPerMinute: Double = 0
    @Published var costTrend: Double = 0

    // Process monitoring
    @Published var isMonitoring: Bool = false
    @Published var isPaused: Bool = false
    @Published var activeProcesses: [ClaudeProcess] = []
    @Published var activeRun: CCRun?

    // History
    @Published var consumptionHistory: [ConsumptionDataPoint] = []
    @Published var recentActivities: [ConsumptionActivity] = []

    // Live session (real-time from cc-live-tracker.py)
    @Published var liveSessionId: String?
    @Published var liveSessionActive: Bool = false
    @Published var liveSessionCost: Double = 0
    @Published var liveSessionDurationSeconds: Double = 0

    // MARK: - Private Properties

    private var monitoringTask: Task<Void, Never>?
    private var liveSessionTask: Task<Void, Never>?
    private var rateCalculationTimer: Timer?
    private var historyTimer: Timer?
    private var cancellables = Set<AnyCancellable>()

    private let ccService = CCTrackingService()
    private var lastCostSnapshot: Double = 0
    private var lastSnapshotTime: Date = Date()
    private var lastLiveSessionUpdate: Date?

    // Token pricing (Claude Opus 4.5)
    private let inputTokenPrice: Double = 15.0 / 1_000_000  // $15 per 1M
    private let outputTokenPrice: Double = 75.0 / 1_000_000 // $75 per 1M
    private let cacheTokenPrice: Double = 1.875 / 1_000_000 // $1.875 per 1M (cache read)

    // MARK: - Initialization

    private init() {
        startMonitoring()
        startRateCalculation()
        startHistoryTracking()
        startLiveSessionMonitoring()
    }

    // Note: deinit cannot call @MainActor methods directly
    // Cleanup is handled when the app terminates

    // MARK: - Public Methods

    var sessionDuration: String {
        let interval = Date().timeIntervalSince(sessionStartTime)
        let hours = Int(interval) / 3600
        let minutes = (Int(interval) % 3600) / 60
        let seconds = Int(interval) % 60

        if hours > 0 {
            return String(format: "%dh %dm %ds", hours, minutes, seconds)
        } else if minutes > 0 {
            return String(format: "%dm %ds", minutes, seconds)
        }
        return String(format: "%ds", seconds)
    }

    func resetSession() {
        sessionCost = 0
        sessionInputTokens = 0
        sessionOutputTokens = 0
        sessionCacheTokens = 0
        sessionStartTime = Date()
        costPerHour = 0
        costPerMinute = 0
        inputTokensPerMinute = 0
        outputTokensPerMinute = 0
        cacheTokensPerMinute = 0
        costTrend = 0
        consumptionHistory.removeAll()
        recentActivities.removeAll()
        lastCostSnapshot = 0
        lastSnapshotTime = Date()

        addActivity(.info, "Session reset")
    }

    func startMonitoring() {
        guard !isMonitoring else { return }
        isMonitoring = true

        monitoringTask = Task {
            await monitorClaudeProcesses()
        }

        addActivity(.info, "Monitoring started")
    }

    func stopMonitoring() {
        isMonitoring = false
        monitoringTask?.cancel()
        monitoringTask = nil
        rateCalculationTimer?.invalidate()
        historyTimer?.invalidate()

        addActivity(.info, "Monitoring stopped")
    }

    // MARK: - Process Monitoring

    private func monitorClaudeProcesses() async {
        while isMonitoring && !Task.isCancelled {
            if !isPaused {
                await detectClaudeProcesses()
                await fetchLatestConsumption()
            }

            try? await Task.sleep(for: .seconds(2))
        }
    }

    private func detectClaudeProcesses() async {
        // Find claude processes using pgrep
        let process = Process()
        process.executableURL = URL(fileURLWithPath: "/usr/bin/pgrep")
        process.arguments = ["-f", "claude"]

        let outputPipe = Pipe()
        process.standardOutput = outputPipe

        do {
            try process.run()
            process.waitUntilExit()

            let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
            let outputString = String(data: outputData, encoding: .utf8) ?? ""

            let pids = outputString.components(separatedBy: .newlines)
                .compactMap { Int($0.trimmingCharacters(in: .whitespaces)) }

            // Get process details for each PID
            var processes: [ClaudeProcess] = []

            for pid in pids {
                if let processInfo = await getProcessInfo(pid: pid) {
                    processes.append(processInfo)
                }
            }

            // Update active processes
            let oldCount = activeProcesses.count
            activeProcesses = processes

            if processes.count != oldCount {
                if processes.count > oldCount {
                    addActivity(.process, "Claude Code process detected (PID: \(processes.last?.pid ?? 0))")
                } else {
                    addActivity(.process, "Claude Code process ended")
                }
            }

        } catch {
            print("Error detecting claude processes: \(error)")
        }
    }

    private func getProcessInfo(pid: Int) async -> ClaudeProcess? {
        // Get process command line
        let process = Process()
        process.executableURL = URL(fileURLWithPath: "/bin/ps")
        process.arguments = ["-p", "\(pid)", "-o", "command=", "-o", "etime=", "-o", "%cpu=", "-o", "%mem="]

        let outputPipe = Pipe()
        process.standardOutput = outputPipe

        do {
            try process.run()
            process.waitUntilExit()

            let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
            let outputString = String(data: outputData, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""

            guard !outputString.isEmpty else { return nil }

            // Parse output
            let components = outputString.components(separatedBy: .whitespaces).filter { !$0.isEmpty }
            guard components.count >= 1 else { return nil }

            // Check if it's actually a claude process
            let command = components.first ?? ""
            guard command.contains("claude") || command.contains("node") else { return nil }

            return ClaudeProcess(
                pid: pid,
                command: command,
                startTime: Date(), // Would need to parse etime properly
                cpuUsage: Double(components.last ?? "0") ?? 0
            )

        } catch {
            return nil
        }
    }

    // MARK: - Consumption Fetching

    private func fetchLatestConsumption() async {
        do {
            // Fetch latest ROI summary from API
            let summary = try await ccService.getROISummary()

            // Calculate delta from last fetch
            let previousCost = sessionCost
            let newTotalCost = summary.totalCost

            // Fetch recent runs to aggregate token data
            let runs = try await ccService.getRecentRuns(limit: 50)

            // Aggregate tokens from today's runs
            var totalInput = 0
            var totalOutput = 0
            var totalCache = 0

            let calendar = Calendar.current
            let today = calendar.startOfDay(for: Date())

            for run in runs {
                if calendar.isDate(run.startedAt, inSameDayAs: today) {
                    totalInput += run.inputTokens
                    totalOutput += run.outputTokens
                    totalCache += run.cacheReadTokens
                }
            }

            // Update session metrics based on today's data
            sessionCost = newTotalCost
            sessionInputTokens = totalInput
            sessionOutputTokens = totalOutput
            sessionCacheTokens = totalCache

            // Track cost trend
            if previousCost > 0 {
                let costDelta = newTotalCost - previousCost
                if costDelta > 0 {
                    addActivity(.cost, "Cost increased", cost: costDelta)
                }
            }

            // Check for active run
            if let latestRun = runs.first, latestRun.status == .running {
                activeRun = latestRun
            } else {
                activeRun = nil
            }

        } catch {
            print("Error fetching consumption: \(error)")
        }
    }

    // MARK: - Rate Calculation

    private func startRateCalculation() {
        rateCalculationTimer = Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { [weak self] _ in
            Task { @MainActor in
                self?.calculateRates()
            }
        }
    }

    private func calculateRates() {
        let now = Date()
        let elapsed = now.timeIntervalSince(lastSnapshotTime)

        guard elapsed > 0 else { return }

        // Calculate cost rate
        let costDelta = sessionCost - lastCostSnapshot
        costPerMinute = (costDelta / elapsed) * 60
        costPerHour = costPerMinute * 60

        // Calculate token rates
        let sessionElapsed = now.timeIntervalSince(sessionStartTime)
        if sessionElapsed > 0 {
            inputTokensPerMinute = Double(sessionInputTokens) / (sessionElapsed / 60)
            outputTokensPerMinute = Double(sessionOutputTokens) / (sessionElapsed / 60)
            cacheTokensPerMinute = Double(sessionCacheTokens) / (sessionElapsed / 60)
        }

        // Calculate trend (% change from last period)
        if lastCostSnapshot > 0 {
            costTrend = ((sessionCost - lastCostSnapshot) / lastCostSnapshot) * 100
        }

        // Update snapshot
        lastCostSnapshot = sessionCost
        lastSnapshotTime = now
    }

    // MARK: - History Tracking

    private func startHistoryTracking() {
        historyTimer = Timer.scheduledTimer(withTimeInterval: 30, repeats: true) { [weak self] _ in
            Task { @MainActor in
                self?.recordHistoryPoint()
            }
        }

        // Record initial point
        recordHistoryPoint()
    }

    private func recordHistoryPoint() {
        let point = ConsumptionDataPoint(
            timestamp: Date(),
            cumulativeCost: sessionCost,
            inputTokens: sessionInputTokens,
            outputTokens: sessionOutputTokens,
            cacheTokens: sessionCacheTokens
        )

        consumptionHistory.append(point)

        // Keep last 2 hours of data (240 points at 30s intervals)
        if consumptionHistory.count > 240 {
            consumptionHistory.removeFirst()
        }
    }

    // MARK: - Live Session Monitoring

    private func startLiveSessionMonitoring() {
        liveSessionTask = Task {
            await monitorLiveSession()
        }
    }

    private func monitorLiveSession() async {
        while !Task.isCancelled {
            if !isPaused {
                await fetchLiveSession()
            }
            try? await Task.sleep(for: .seconds(1)) // Faster polling for live data
        }
    }

    private func fetchLiveSession() async {
        guard let url = URL(string: "http://localhost:9001/api/cc/session/current") else { return }

        do {
            let (data, response) = try await URLSession.shared.data(from: url)

            guard let httpResponse = response as? HTTPURLResponse,
                  httpResponse.statusCode == 200 else {
                liveSessionActive = false
                return
            }

            let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]

            if let active = json?["active"] as? Bool, active {
                // Live session is active
                let sessionId = json?["session_id"] as? String
                let cost = json?["cumulative_cost"] as? Double ?? 0
                let duration = json?["duration_seconds"] as? Double ?? 0
                let costRate = json?["cost_rate_per_hour"] as? Double ?? 0
                let tokens = json?["cumulative_tokens"] as? [String: Any]

                // Update live session state
                if liveSessionId != sessionId {
                    // New session detected
                    addActivity(.process, "Live session started: \(sessionId ?? "unknown")")
                }

                liveSessionId = sessionId
                liveSessionActive = true
                liveSessionCost = cost
                liveSessionDurationSeconds = duration

                // Update main metrics from live session
                if let tokens = tokens {
                    let input = tokens["input"] as? Int ?? 0
                    let output = tokens["output"] as? Int ?? 0
                    let cacheRead = tokens["cacheRead"] as? Int ?? 0

                    // Update session tokens if live data is newer
                    if input > sessionInputTokens || output > sessionOutputTokens {
                        sessionInputTokens = input
                        sessionOutputTokens = output
                        sessionCacheTokens = cacheRead
                    }
                }

                // Update cost rate from live session
                if costRate > 0 {
                    costPerHour = costRate
                    costPerMinute = costRate / 60
                }

                // Update session cost if live is higher
                if cost > sessionCost {
                    let costDelta = cost - sessionCost
                    sessionCost = cost
                    if costDelta > 0.0001 {
                        addActivity(.cost, "Live cost update", cost: costDelta)
                    }
                }

                lastLiveSessionUpdate = Date()

            } else {
                // No active live session
                if liveSessionActive {
                    addActivity(.process, "Live session ended")
                }
                liveSessionActive = false
                liveSessionId = nil
            }

        } catch {
            // API not available or error
            if liveSessionActive {
                liveSessionActive = false
            }
        }
    }

    // MARK: - Activity Logging

    private func addActivity(_ type: ConsumptionActivity.ActivityType, _ description: String, cost: Double? = nil) {
        let activity = ConsumptionActivity(
            type: type,
            description: description,
            timestamp: Date(),
            cost: cost
        )

        recentActivities.insert(activity, at: 0)

        // Keep last 50 activities
        if recentActivities.count > 50 {
            recentActivities.removeLast()
        }
    }
}

// MARK: - Supporting Types

struct ClaudeProcess: Identifiable {
    let id = UUID()
    let pid: Int
    let command: String
    let startTime: Date
    let cpuUsage: Double
}

struct ConsumptionDataPoint: Identifiable {
    let id = UUID()
    let timestamp: Date
    let cumulativeCost: Double
    let inputTokens: Int
    let outputTokens: Int
    let cacheTokens: Int
}

struct ConsumptionActivity: Identifiable {
    let id = UUID()
    let type: ActivityType
    let description: String
    let timestamp: Date
    let cost: Double?

    enum ActivityType {
        case info
        case cost
        case tokens
        case process
        case warning
        case error

        var color: Color {
            switch self {
            case .info: return .blue
            case .cost: return .green
            case .tokens: return .purple
            case .process: return .orange
            case .warning: return .yellow
            case .error: return .red
            }
        }
    }
}


Now let me check the backend services directory:


Bash

List Python backend services


find /Users/neog/Services/servers -name "*.py" -type f | head -10

Find Python server files


total 672
drwxr-xr-x@ 21 neog  staff     672 Dec 25 02:29 .
drwxr-xr-x@  9 neog  staff     288 Dec 21 21:47 ..
drwxr-xr-x@ 12 neog  staff     384 Dec 21 18:55 .git
-rw-------@  1 neog  staff   19541 Dec 20 16:29 abr-telecom-server.py
-rw-r--r--@  1 neog  staff   19619 Oct 21 21:02 bitcoin-monitor-server.py
-rw-------@  1 neog  staff    9496 Dec 25 01:45 cc-live-tracker.py
-rw-------@  1 neog  staff   18245 Nov 28 15:24 claude-cli-server.py
-rw-r--r--@  1 neog  staff   11843 Oct 25 19:39 crypto-grok-server.py
-rw-------@  1 neog  staff   13288 Nov 26 08:33 domain-validator-server.py
-rw-r--r--@  1 neog  staff     826 Oct  5 12:06 https_server.py
-rwxr-xr-x@  1 neog  staff  109745 Dec 25 01:59 log-server.py
-rwxr-xr-x@  1 neog  staff    9598 Oct  8 17:07 scraper_server.py
-rwx--x--x@  1 neog  staff    2250 Dec 25 02:29 start-all-services.sh
-rwxr-xr-x@  1 neog  staff   13648 Oct 15 15:43 system-metrics-server.py
-rwxr-xr-x@  1 neog  staff   14030 Oct  7 16:35 system-monitor-server-v2.py
-rwxr-xr-x@  1 neog  staff   11516 Oct  7 16:00 system-monitor-server.py
-rw-------@  1 neog  staff    9946 Nov 15 19:49 terminal-remote-server.py
-rw-------@  1 neog  staff    5551 Dec  4 02:19 transcript-server.py
-rwxr-xr-x@  1 neog  staff    7144 Oct  6 19:10 wifi-api-server.py
-rw-------@  1 neog  staff   18329 Dec 13 13:57 workspace-manager-api.py
-rw-------@  1 neog  staff   15923 Dec 21 18:08 youtube-audio-server.py


/Users/neog/Services/servers/terminal-remote-server.py
/Users/neog/Services/servers/scraper_server.py
/Users/neog/Services/servers/abr-telecom-server.py
/Users/neog/Services/servers/domain-validator-server.py
/Users/neog/Services/servers/cc-live-tracker.py
/Users/neog/Services/servers/workspace-manager-api.py
/Users/neog/Services/servers/wifi-api-server.py
/Users/neog/Services/servers/log-server.py
/Users/neog/Services/servers/system-monitor-server-v2.py
/Users/neog/Services/servers/claude-cli-server.py


Let me examine the key backend servers:


     1→#!/usr/bin/env python3
     2→"""
     3→NEOG OS - Centralized Log Server
     4→Collects logs from all NEOG clients across Tailscale network
     5→"""
     6→
     7→from flask import Flask, request, jsonify, send_from_directory
     8→from flask_cors import CORS
     9→from flask_socketio import SocketIO, emit
    10→import sqlite3
    11→import json
    12→import time
    13→from datetime import datetime
    14→import os
    15→import sys
    16→import subprocess
    17→sys.path.append('/Users/neog')
    18→from markdown_converter import generate_html_page
    19→
    20→# ========== NOTIFICATION HELPERS ==========
    21→
    22→# Webhook configuration (set via API or environment)
    23→WEBHOOK_CONFIG = {
    24→    'slack': os.environ.get('CC_SLACK_WEBHOOK', ''),
    25→    'discord': os.environ.get('CC_DISCORD_WEBHOOK', ''),
    26→    'enabled': True
    27→}
    28→
    29→def send_macos_notification(title, message, subtitle=None, sound='default'):
    30→    """Send a macOS notification using osascript"""
    31→    try:
    32→        script = f'display notification "{message}"'
    33→        if subtitle:
    34→            script += f' subtitle "{subtitle}"'
    35→        script += f' with title "{title}"'
    36→        if sound:
    37→            script += f' sound name "{sound}"'
    38→        subprocess.run(['osascript', '-e', script], check=False, timeout=5)
    39→    except Exception as e:
    40→        print(f"[NOTIFY] Failed to send notification: {e}")
    41→
    42→def send_webhook_notification(title, message, level='info'):
    43→    """Send notification to configured webhooks (Slack/Discord)"""
    44→    import requests
    45→
    46→    if not WEBHOOK_CONFIG['enabled']:
    47→        return
    48→
    49→    # Color mapping
    50→    colors = {
    51→        'info': '#00d4ff',
    52→        'success': '#10b981',
    53→        'warning': '#f59e0b',
    54→        'error': '#ef4444'
    55→    }
    56→    color = colors.get(level, colors['info'])
    57→
    58→    # Slack webhook
    59→    if WEBHOOK_CONFIG.get('slack'):
    60→        try:
    61→            requests.post(WEBHOOK_CONFIG['slack'], json={
    62→                'attachments': [{
    63→                    'color': color,
    64→                    'title': title,
    65→                    'text': message,
    66→                    'footer': 'CC ROI Dashboard',
    67→                    'ts': int(datetime.now().timestamp())
    68→                }]
    69→            }, timeout=5)
    70→        except Exception as e:
    71→            print(f"[WEBHOOK] Slack failed: {e}")
    72→
    73→    # Discord webhook
    74→    if WEBHOOK_CONFIG.get('discord'):
    75→        try:
    76→            # Convert hex to int for Discord
    77→            color_int = int(color.lstrip('#'), 16)
    78→            requests.post(WEBHOOK_CONFIG['discord'], json={
    79→                'embeds': [{
    80→                    'title': title,
    81→                    'description': message,
    82→                    'color': color_int,
    83→                    'footer': {'text': 'CC ROI Dashboard'}
    84→                }]
    85→            }, timeout=5)
    86→        except Exception as e:
    87→            print(f"[WEBHOOK] Discord failed: {e}")
    88→
    89→def send_alert(title, message, level='info', subtitle=None):
    90→    """Send alert via all configured channels"""
    91→    # Always send macOS notification
    92→    sound = 'Basso' if level == 'error' else 'default'
    93→    send_macos_notification(title, message, subtitle, sound)
    94→
    95→    # Send to webhooks if configured
    96→    send_webhook_notification(title, message, level)
    97→
    98→app = Flask(__name__, static_folder='/Users/neog/static')
    99→CORS(app)
   100→socketio = SocketIO(app, cors_allowed_origins="*")
   101→
   102→DB_PATH = '/Users/neog/logs.db'
   103→
   104→# ========== LIVE SESSION TRACKING ==========
   105→# Stores real-time session data from cc-live-tracker.py
   106→CURRENT_LIVE_SESSION = {
   107→    'session_id': None,
   108→    'started_at': None,
   109→    'last_update': None,
   110→    'cumulative_cost': 0.0,
   111→    'cumulative_tokens': {
   112→        'input': 0,
   113→        'output': 0,
   114→        'cacheRead': 0,
   115→        'cacheCreation': 0
   116→    },
   117→    'duration_seconds': 0,
   118→    'updates': []  # Last 10 deltas for rate calculation
   119→}
   120→
   121→def init_db():
   122→    """Initialize SQLite database with logs table and CC tracking tables"""
   123→    conn = sqlite3.connect(DB_PATH)
   124→    c = conn.cursor()
   125→
   126→    # Original logs table
   127→    c.execute('''CREATE TABLE IF NOT EXISTS logs
   128→                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
   129→                  timestamp TEXT NOT NULL,
   130→                  level TEXT NOT NULL,
   131→                  source TEXT NOT NULL,
   132→                  message TEXT NOT NULL,
   133→                  data TEXT,
   134→                  device_ip TEXT,
   135→                  user_agent TEXT,
   136→                  url TEXT,
   137→                  created_at DATETIME DEFAULT CURRENT_TIMESTAMP)''')
   138→
   139→    # Create indexes for faster queries
   140→    c.execute('CREATE INDEX IF NOT EXISTS idx_timestamp ON logs(timestamp)')
   141→    c.execute('CREATE INDEX IF NOT EXISTS idx_level ON logs(level)')
   142→    c.execute('CREATE INDEX IF NOT EXISTS idx_source ON logs(source)')
   143→    c.execute('CREATE INDEX IF NOT EXISTS idx_device_ip ON logs(device_ip)')
   144→
   145→    # ========== CC TRACKING TABLES (Automation ROI Dashboard) ==========
   146→
   147→    # cc_runs: Track automation execution sessions
   148→    c.execute('''CREATE TABLE IF NOT EXISTS cc_runs (
   149→        run_id TEXT PRIMARY KEY,
   150→        session_id TEXT,

<system-reminder>
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.
</system-reminder>

#!/usr/bin/env python3
"""
NEOG OS - Centralized Log Server
Collects logs from all NEOG clients across Tailscale network
"""

from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
from flask_socketio import SocketIO, emit
import sqlite3
import json
import time
from datetime import datetime
import os
import sys
import subprocess
sys.path.append('/Users/neog')
from markdown_converter import generate_html_page

# ========== NOTIFICATION HELPERS ==========

# Webhook configuration (set via API or environment)
WEBHOOK_CONFIG = {
    'slack': os.environ.get('CC_SLACK_WEBHOOK', ''),
    'discord': os.environ.get('CC_DISCORD_WEBHOOK', ''),
    'enabled': True
}

def send_macos_notification(title, message, subtitle=None, sound='default'):
    """Send a macOS notification using osascript"""
    try:
        script = f'display notification "{message}"'
        if subtitle:
            script += f' subtitle "{subtitle}"'
        script += f' with title "{title}"'
        if sound:
            script += f' sound name "{sound}"'
        subprocess.run(['osascript', '-e', script], check=False, timeout=5)
    except Exception as e:
        print(f"[NOTIFY] Failed to send notification: {e}")

def send_webhook_notification(title, message, level='info'):
    """Send notification to configured webhooks (Slack/Discord)"""
    import requests

    if not WEBHOOK_CONFIG['enabled']:
        return

    # Color mapping
    colors = {
        'info': '#00d4ff',
        'success': '#10b981',
        'warning': '#f59e0b',
        'error': '#ef4444'
    }
    color = colors.get(level, colors['info'])

    # Slack webhook
    if WEBHOOK_CONFIG.get('slack'):
        try:
            requests.post(WEBHOOK_CONFIG['slack'], json={
                'attachments': [{
                    'color': color,
                    'title': title,
                    'text': message,
                    'footer': 'CC ROI Dashboard',
                    'ts': int(datetime.now().timestamp())
                }]
            }, timeout=5)
        except Exception as e:
            print(f"[WEBHOOK] Slack failed: {e}")

    # Discord webhook
    if WEBHOOK_CONFIG.get('discord'):
        try:
            # Convert hex to int for Discord
            color_int = int(color.lstrip('#'), 16)
            requests.post(WEBHOOK_CONFIG['discord'], json={
                'embeds': [{
                    'title': title,
                    'description': message,
                    'color': color_int,
                    'footer': {'text': 'CC ROI Dashboard'}
                }]
            }, timeout=5)
        except Exception as e:
            print(f"[WEBHOOK] Discord failed: {e}")

def send_alert(title, message, level='info', subtitle=None):
    """Send alert via all configured channels"""
    # Always send macOS notification
    sound = 'Basso' if level == 'error' else 'default'
    send_macos_notification(title, message, subtitle, sound)

    # Send to webhooks if configured
    send_webhook_notification(title, message, level)

app = Flask(__name__, static_folder='/Users/neog/static')
CORS(app)
socketio = SocketIO(app, cors_allowed_origins="*")

DB_PATH = '/Users/neog/logs.db'

# ========== LIVE SESSION TRACKING ==========
# Stores real-time session data from cc-live-tracker.py
CURRENT_LIVE_SESSION = {
    'session_id': None,
    'started_at': None,
    'last_update': None,
    'cumulative_cost': 0.0,
    'cumulative_tokens': {
        'input': 0,
        'output': 0,
        'cacheRead': 0,
        'cacheCreation': 0
    },
    'duration_seconds': 0,
    'updates': []  # Last 10 deltas for rate calculation
}

def init_db():
    """Initialize SQLite database with logs table and CC tracking tables"""
    conn = sqlite3.connect(DB_PATH)
    c = conn.cursor()

    # Original logs table
    c.execute('''CREATE TABLE IF NOT EXISTS logs
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  timestamp TEXT NOT NULL,
                  level TEXT NOT NULL,
                  source TEXT NOT NULL,
                  message TEXT NOT NULL,
                  data TEXT,
                  device_ip TEXT,
                  user_agent TEXT,
                  url TEXT,
                  created_at DATETIME DEFAULT CURRENT_TIMESTAMP)''')

    # Create indexes for faster queries
    c.execute('CREATE INDEX IF NOT EXISTS idx_timestamp ON logs(timestamp)')
    c.execute('CREATE INDEX IF NOT EXISTS idx_level ON logs(level)')
    c.execute('CREATE INDEX IF NOT EXISTS idx_source ON logs(source)')
    c.execute('CREATE INDEX IF NOT EXISTS idx_device_ip ON logs(device_ip)')

    # ========== CC TRACKING TABLES (Automation ROI Dashboard) ==========

    # cc_runs: Track automation execution sessions
    c.execute('''CREATE TABLE IF NOT EXISTS cc_runs (
        run_id TEXT PRIMARY KEY,
        session_id TEXT,


     1→#!/usr/bin/env python3
     2→"""
     3→Real macOS System Monitor Server
     4→Exposes real hardware data via HTTP API
     5→"""
     6→
     7→from flask import Flask, jsonify
     8→from flask_cors import CORS
     9→import subprocess
    10→import json
    11→import psutil
    12→import platform
    13→import re
    14→from datetime import datetime
    15→
    16→app = Flask(__name__)
    17→CORS(app)
    18→
    19→def run_command(cmd):
    20→    """Execute shell command and return output"""
    21→    try:
    22→        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=5)
    23→        return result.stdout.strip()
    24→    except Exception as e:
    25→        print(f"[Error] Command failed: {cmd} - {e}")
    26→        return ""
    27→
    28→def get_cpu_info():
    29→    """Get real CPU information"""
    30→    try:
    31→        # macOS sysctl for CPU info
    32→        brand = run_command("sysctl -n machdep.cpu.brand_string")
    33→        cores = run_command("sysctl -n hw.ncpu")
    34→        performance_cores = run_command("sysctl -n hw.perflevel0.logicalcpu 2>/dev/null") or "0"
    35→        efficiency_cores = run_command("sysctl -n hw.perflevel1.logicalcpu 2>/dev/null") or "0"
    36→
    37→        # CPU usage per core
    38→        cpu_percent = psutil.cpu_percent(interval=0.1, percpu=True)
    39→
    40→        return {
    41→            'brand': brand,
    42→            'total_cores': int(cores) if cores else psutil.cpu_count(),
    43→            'performance_cores': int(performance_cores) if performance_cores != "0" else None,
    44→            'efficiency_cores': int(efficiency_cores) if efficiency_cores != "0" else None,
    45→            'usage_percent': psutil.cpu_percent(interval=0.1),
    46→            'usage_per_core': cpu_percent,
    47→            'frequency_mhz': psutil.cpu_freq().current if psutil.cpu_freq() else None
    48→        }
    49→    except Exception as e:
    50→        print(f"[Error] get_cpu_info: {e}")
    51→        return {'error': str(e)}
    52→
    53→def get_gpu_info():
    54→    """Get GPU information (Apple Silicon)"""
    55→    try:
    56→        # Try to get GPU info from system_profiler
    57→        gpu_raw = run_command("system_profiler SPDisplaysDataType -json 2>/dev/null")
    58→
    59→        if gpu_raw:
    60→            gpu_data = json.loads(gpu_raw)
    61→            displays = gpu_data.get('SPDisplaysDataType', [])
    62→
    63→            gpu_info = []
    64→            for display in displays:
    65→                chipset = display.get('sppci_model', 'Unknown')
    66→                vram = display.get('spdisplays_vram', 'Unknown')
    67→                gpu_info.append({
    68→                    'name': chipset,
    69→                    'vram': vram,
    70→                    'type': 'Integrated' if 'Apple' in chipset else 'Discrete'
    71→                })
    72→
    73→            return gpu_info if gpu_info else [{'name': 'Unknown GPU', 'vram': 'N/A'}]
    74→
    75→        # Fallback: try to detect Apple Silicon GPU
    76→        brand = run_command("sysctl -n machdep.cpu.brand_string")
    77→        if 'Apple' in brand:
    78→            # Extract M-series chip info
    79→            m_chip = re.search(r'Apple (M\d+[^\s]*)', brand)
    80→            if m_chip:
    81→                chip_name = m_chip.group(1)
    82→                return [{'name': f'{chip_name} GPU', 'vram': 'Unified Memory', 'type': 'Integrated'}]
    83→
    84→        return [{'name': 'Unknown GPU', 'vram': 'N/A'}]
    85→
    86→    except Exception as e:
    87→        print(f"[Error] get_gpu_info: {e}")
    88→        return [{'error': str(e)}]
    89→
    90→def get_memory_info():
    91→    """Get real memory information"""
    92→    try:
    93→        mem = psutil.virtual_memory()
    94→        swap = psutil.swap_memory()
    95→
    96→        return {
    97→            'total_gb': round(mem.total / (1024**3), 2),
    98→            'used_gb': round(mem.used / (1024**3), 2),
    99→            'available_gb': round(mem.available / (1024**3), 2),
   100→            'percent': mem.percent,

<system-reminder>
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.
</system-reminder>

#!/usr/bin/env python3
"""
Real macOS System Monitor Server
Exposes real hardware data via HTTP API
"""

from flask import Flask, jsonify
from flask_cors import CORS
import subprocess
import json
import psutil
import platform
import re
from datetime import datetime

app = Flask(__name__)
CORS(app)

def run_command(cmd):
    """Execute shell command and return output"""
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=5)
        return result.stdout.strip()
    except Exception as e:
        print(f"[Error] Command failed: {cmd} - {e}")
        return ""

def get_cpu_info():
    """Get real CPU information"""
    try:
        # macOS sysctl for CPU info
        brand = run_command("sysctl -n machdep.cpu.brand_string")
        cores = run_command("sysctl -n hw.ncpu")
        performance_cores = run_command("sysctl -n hw.perflevel0.logicalcpu 2>/dev/null") or "0"
        efficiency_cores = run_command("sysctl -n hw.perflevel1.logicalcpu 2>/dev/null") or "0"

        # CPU usage per core
        cpu_percent = psutil.cpu_percent(interval=0.1, percpu=True)

        return {
            'brand': brand,
            'total_cores': int(cores) if cores else psutil.cpu_count(),
            'performance_cores': int(performance_cores) if performance_cores != "0" else None,
            'efficiency_cores': int(efficiency_cores) if efficiency_cores != "0" else None,
            'usage_percent': psutil.cpu_percent(interval=0.1),
            'usage_per_core': cpu_percent,
            'frequency_mhz': psutil.cpu_freq().current if psutil.cpu_freq() else None
        }
    except Exception as e:
        print(f"[Error] get_cpu_info: {e}")
        return {'error': str(e)}

def get_gpu_info():
    """Get GPU information (Apple Silicon)"""
    try:
        # Try to get GPU info from system_profiler
        gpu_raw = run_command("system_profiler SPDisplaysDataType -json 2>/dev/null")

        if gpu_raw:
            gpu_data = json.loads(gpu_raw)
            displays = gpu_data.get('SPDisplaysDataType', [])

            gpu_info = []
            for display in displays:
                chipset = display.get('sppci_model', 'Unknown')
                vram = display.get('spdisplays_vram', 'Unknown')
                gpu_info.append({
                    'name': chipset,
                    'vram': vram,
                    'type': 'Integrated' if 'Apple' in chipset else 'Discrete'
                })

            return gpu_info if gpu_info else [{'name': 'Unknown GPU', 'vram': 'N/A'}]

        # Fallback: try to detect Apple Silicon GPU
        brand = run_command("sysctl -n machdep.cpu.brand_string")
        if 'Apple' in brand:
            # Extract M-series chip info
            m_chip = re.search(r'Apple (M\d+[^\s]*)', brand)
            if m_chip:
                chip_name = m_chip.group(1)
                return [{'name': f'{chip_name} GPU', 'vram': 'Unified Memory', 'type': 'Integrated'}]

        return [{'name': 'Unknown GPU', 'vram': 'N/A'}]

    except Exception as e:
        print(f"[Error] get_gpu_info: {e}")
        return [{'error': str(e)}]

def get_memory_info():
    """Get real memory information"""
    try:
        mem = psutil.virtual_memory()
        swap = psutil.swap_memory()

        return {
            'total_gb': round(mem.total / (1024**3), 2),
            'used_gb': round(mem.used / (1024**3), 2),
            'available_gb': round(mem.available / (1024**3), 2),
            'percent': mem.percent,


     1→#!/usr/bin/env python3
     2→
     3→"""
     4→WiFi API Server - NEOG System
     5→Serves real WiFi network data via REST API
     6→Port: 9002 (NEOG Log Server uses 9001)
     7→"""
     8→
     9→import json
    10→import subprocess
    11→import time
    12→from datetime import datetime
    13→from flask import Flask, jsonify, request
    14→from flask_cors import CORS
    15→import threading
    16→
    17→app = Flask(__name__)
    18→CORS(app)  # Enable CORS for all routes
    19→
    20→# Global cache
    21→wifi_cache = {
    22→    'data': None,
    23→    'timestamp': 0,
    24→    'scan_in_progress': False
    25→}
    26→
    27→CACHE_TTL = 5  # seconds
    28→SWIFT_SCANNER_PATH = '/Users/neog/wifi-scanner.swift'
    29→
    30→def run_wifi_scan():
    31→    """Execute Swift WiFi scanner and return parsed JSON"""
    32→    try:
    33→        result = subprocess.run(
    34→            ['swift', SWIFT_SCANNER_PATH],
    35→            capture_output=True,
    36→            text=True,
    37→            timeout=15
    38→        )
    39→
    40→        if result.returncode == 0:
    41→            try:
    42→                data = json.loads(result.stdout)
    43→                return data
    44→            except json.JSONDecodeError as e:
    45→                print(f"[ERROR] JSON decode failed: {e}")
    46→                print(f"[DEBUG] Output: {result.stdout[:200]}")
    47→                return {
    48→                    'success': False,
    49→                    'error': f'JSON parse error: {str(e)}',
    50→                    'networks': []
    51→                }
    52→        else:
    53→            print(f"[ERROR] Scanner failed: {result.stderr}")
    54→            return {
    55→                'success': False,
    56→                'error': result.stderr or 'Scanner execution failed',
    57→                'networks': []
    58→            }
    59→
    60→    except subprocess.TimeoutExpired:
    61→        print("[ERROR] Scanner timeout")
    62→        return {
    63→            'success': False,
    64→            'error': 'Scanner timeout (15s)',
    65→            'networks': []
    66→        }
    67→    except Exception as e:
    68→        print(f"[ERROR] Scan exception: {e}")
    69→        return {
    70→            'success': False,
    71→            'error': str(e),
    72→            'networks': []
    73→        }
    74→
    75→def get_wifi_networks(force_refresh=False):
    76→    """Get WiFi networks with caching"""
    77→    global wifi_cache
    78→
    79→    current_time = time.time()
    80→
    81→    # Return cached data if valid
    82→    if not force_refresh and wifi_cache['data'] and (current_time - wifi_cache['timestamp']) < CACHE_TTL:
    83→        cache_age = int(current_time - wifi_cache['timestamp'])
    84→        print(f"[CACHE HIT] Age: {cache_age}s")
    85→        wifi_cache['data']['cached'] = True
    86→        wifi_cache['data']['cache_age'] = cache_age
    87→        return wifi_cache['data']
    88→
    89→    # Prevent concurrent scans
    90→    if wifi_cache['scan_in_progress']:
    91→        print("[SCAN] Already in progress, returning cached data")
    92→        if wifi_cache['data']:
    93→            wifi_cache['data']['cached'] = True
    94→            return wifi_cache['data']
    95→        return {
    96→            'success': False,
    97→            'error': 'Scan in progress',
    98→            'networks': []
    99→        }
   100→

<system-reminder>
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.
</system-reminder>

#!/usr/bin/env python3

"""
WiFi API Server - NEOG System
Serves real WiFi network data via REST API
Port: 9002 (NEOG Log Server uses 9001)
"""

import json
import subprocess
import time
from datetime import datetime
from flask import Flask, jsonify, request
from flask_cors import CORS
import threading

app = Flask(__name__)
CORS(app)  # Enable CORS for all routes

# Global cache
wifi_cache = {
    'data': None,
    'timestamp': 0,
    'scan_in_progress': False
}

CACHE_TTL = 5  # seconds
SWIFT_SCANNER_PATH = '/Users/neog/wifi-scanner.swift'

def run_wifi_scan():
    """Execute Swift WiFi scanner and return parsed JSON"""
    try:
        result = subprocess.run(
            ['swift', SWIFT_SCANNER_PATH],
            capture_output=True,
            text=True,
            timeout=15
        )

        if result.returncode == 0:
            try:
                data = json.loads(result.stdout)
                return data
            except json.JSONDecodeError as e:
                print(f"[ERROR] JSON decode failed: {e}")
                print(f"[DEBUG] Output: {result.stdout[:200]}")
                return {
                    'success': False,
                    'error': f'JSON parse error: {str(e)}',
                    'networks': []
                }
        else:
            print(f"[ERROR] Scanner failed: {result.stderr}")
            return {
                'success': False,
                'error': result.stderr or 'Scanner execution failed',
                'networks': []
            }

    except subprocess.TimeoutExpired:
        print("[ERROR] Scanner timeout")
        return {
            'success': False,
            'error': 'Scanner timeout (15s)',
            'networks': []
        }
    except Exception as e:
        print(f"[ERROR] Scan exception: {e}")
        return {
            'success': False,
            'error': str(e),
            'networks': []
        }

def get_wifi_networks(force_refresh=False):
    """Get WiFi networks with caching"""
    global wifi_cache

    current_time = time.time()

    # Return cached data if valid
    if not force_refresh and wifi_cache['data'] and (current_time - wifi_cache['timestamp']) < CACHE_TTL:
        cache_age = int(current_time - wifi_cache['timestamp'])
        print(f"[CACHE HIT] Age: {cache_age}s")
        wifi_cache['data']['cached'] = True
        wifi_cache['data']['cache_age'] = cache_age
        return wifi_cache['data']

    # Prevent concurrent scans
    if wifi_cache['scan_in_progress']:
        print("[SCAN] Already in progress, returning cached data")
        if wifi_cache['data']:
            wifi_cache['data']['cached'] = True
            return wifi_cache['data']
        return {
            'success': False,
            'error': 'Scan in progress',
            'networks': []
        }


Now let me check a bit more of the log server to understand the CC ROI endpoints:


grep -n "def.*:" /Users/neog/Services/servers/log-server.py | head -30

Find all endpoints in log-server


150→        session_id TEXT,
   151→        prompt TEXT NOT NULL,
   152→        source TEXT DEFAULT 'manual',
   153→        device_ip TEXT,
   154→        status TEXT DEFAULT 'pending',
   155→
   156→        input_tokens INTEGER DEFAULT 0,
   157→        output_tokens INTEGER DEFAULT 0,
   158→        cache_read_tokens INTEGER DEFAULT 0,
   159→        model TEXT DEFAULT 'claude-opus-4-5-20251101',
   160→
   161→        cost_usd REAL DEFAULT 0,
   162→        value_generated_usd REAL DEFAULT 0,
   163→
   164→        gate_guardrails_ok BOOLEAN DEFAULT 1,
   165→        gate_budget_ok BOOLEAN DEFAULT 1,
   166→        gate_heartbeat_ok BOOLEAN DEFAULT 1,
   167→        halt_reason TEXT,
   168→
   169→        started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
   170→        completed_at DATETIME,
   171→        duration_ms INTEGER,
   172→
   173→        tools_used TEXT,
   174→        files_modified TEXT,
   175→        error_message TEXT,
   176→        tags TEXT
   177→    )''')
   178→
   179→    # cc_tags: Predefined tags for categorization
   180→    c.execute('''CREATE TABLE IF NOT EXISTS cc_tags (
   181→        id INTEGER PRIMARY KEY AUTOINCREMENT,
   182→        name TEXT UNIQUE NOT NULL,
   183→        color TEXT DEFAULT '#00d4ff',
   184→        description TEXT,
   185→        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
   186→    )''')
   187→
   188→    # Seed default tags
   189→    default_tags = [
   190→        ('feature', '#10b981', 'New feature development'),
   191→        ('bugfix', '#ef4444', 'Bug fixes'),
   192→        ('refactor', '#f59e0b', 'Code refactoring'),
   193→        ('docs', '#6366f1', 'Documentation'),
   194→        ('test', '#8b5cf6', 'Testing'),
   195→        ('devops', '#ec4899', 'DevOps and infrastructure'),
   196→        ('research', '#14b8a6', 'Research and exploration')
   197→    ]
   198→    for tag_name, color, desc in default_tags:
   199→        c.execute('INSERT OR IGNORE INTO cc_tags (name, color, description) VALUES (?, ?, ?)',
   200→                  (tag_name, color, desc))
   201→
   202→    # cc_events: Granular events within each run (feedback loop)
   203→    c.execute('''CREATE TABLE IF NOT EXISTS cc_events (
   204→        id INTEGER PRIMARY KEY AUTOINCREMENT,
   205→        run_id TEXT NOT NULL,
   206→        event_type TEXT NOT NULL,
   207→        event_subtype TEXT,
   208→
   209→        input_tokens INTEGER DEFAULT 0,
   210→        output_tokens INTEGER DEFAULT 0,
   211→        cost_usd REAL DEFAULT 0,
   212→
   213→        input_data TEXT,
   214→        output_data TEXT,
   215→        duration_ms INTEGER,
   216→        success BOOLEAN DEFAULT 1,
   217→
   218→        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
   219→        FOREIGN KEY (run_id) REFERENCES cc_runs(run_id)
   220→    )''')
   221→
   222→    # budget_config: 3-Gate budget limits
   223→    c.execute('''CREATE TABLE IF NOT EXISTS budget_config (
   224→        id INTEGER PRIMARY KEY,
   225→        name TEXT UNIQUE NOT NULL,
   226→        daily_limit_usd REAL DEFAULT 10.00,
   227→        monthly_limit_usd REAL DEFAULT 200.00,
   228→        max_tokens_per_run INTEGER DEFAULT 100000,
   229→        max_cost_per_run_usd REAL DEFAULT 2.00,
   230→        alert_threshold_pct INTEGER DEFAULT 80,
   231→        is_active BOOLEAN DEFAULT 1,
   232→        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
   233→    )''')
   234→
   235→    # guardrails: Safety rules
   236→    c.execute('''CREATE TABLE IF NOT EXISTS guardrails (
   237→        id INTEGER PRIMARY KEY AUTOINCREMENT,
   238→        name TEXT NOT NULL,
   239→        rule_type TEXT NOT NULL,
   240→        pattern TEXT NOT NULL,
   241→        action TEXT DEFAULT 'block',
   242→        is_active BOOLEAN DEFAULT 1,
   243→        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
   244→    )''')
   245→
   246→    # CC indexes
   247→    c.execute('CREATE INDEX IF NOT EXISTS idx_cc_runs_status ON cc_runs(status)')
   248→    c.execute('CREATE INDEX IF NOT EXISTS idx_cc_runs_started ON cc_runs(started_at)')
   249→    c.execute('CREATE INDEX IF NOT EXISTS idx_cc_events_run ON cc_events(run_id)')
   250→    c.execute('CREATE INDEX IF NOT EXISTS idx_cc_events_type ON cc_events(event_type)')
   251→
   252→    # Seed default budget config
   253→    c.execute('''INSERT OR IGNORE INTO budget_config (id, name, daily_limit_usd, monthly_limit_usd)
   254→                 VALUES (1, 'default', 10.00, 200.00)''')
   255→
   256→    # Seed default guardrails
   257→    guardrails_seed = [
   258→        ('block_rm_rf', 'blocked_command', 'rm -rf /', 'block'),
   259→        ('block_rm_rf_home', 'blocked_command', 'rm -rf ~', 'block'),
   260→        ('block_sudo', 'blocked_command', 'sudo', 'warn'),
   261→        ('block_force_push', 'blocked_command', 'git push --force', 'warn'),
   262→        ('block_force_push_main', 'blocked_command', 'git push -f origin main', 'block'),
   263→        ('block_secrets', 'blocked_path', '**/*secret*', 'block'),
   264→        ('block_env', 'blocked_path', '.env', 'warn'),
   265→        ('block_ssh', 'blocked_path', '.ssh', 'block'),
   266→    ]
   267→    for name, rule_type, pattern, action in guardrails_seed:
   268→        c.execute('''INSERT OR IGNORE INTO guardrails (name, rule_type, pattern, action)
   269→                     VALUES (?, ?, ?, ?)''', (name, rule_type, pattern, action))
   270→
   271→    conn.commit()
   272→    conn.close()
   273→    print(f"✓ Database initialized at {DB_PATH}")
   274→    print(f"✓ CC tracking tables ready (cc_runs, cc_events, budget_config, guardrails)")
   275→
   276→@app.route('/')
   277→def index():
   278→    """Redirect to live dashboard"""
   279→    return '''
   280→
   281→        <title>NEOG Log Server</title>
   282→
   283→
🔍 NEOG OS - Log Server

   284→
Server is running on port 9001

   285→

   286→
📊 Automation ROI Dashboard (NEW)

   287→
Live Dashboard

   288→
Metrics Dashboard (PWA)

   289→
Statistics (JSON)

   290→
Recent Logs (JSON)

   291→

   292→
📈 CC Tracking API

   293→

   294→
System Status

   295→
Gate Health

   296→
ROI Summary

   297→
Recent Runs

   298→
Budget Status

   299→
Guardrails

   300→

   301→
   302→
   303→    '''
   304→
   305→@app.route('/dashboard')
   306→def dashboard():
   307→    """Serve live dashboard"""
   308→    return send_from_directory('/Users/neog', 'neog-logs-live.html')
   309→
   310→@app.route('/metrics')
   311→def metrics():
   312→    """Serve advanced metrics dashboard (PWA)"""
   313→    return send_from_directory('/Users/neog', 'neog-metrics.html')
   314→
   315→# Serve PWA static files
   316→@app.route('/static/<path:filename>')
   317→def serve_static(filename):
   318→    """Serve static files (PWA assets)"""
   319→    return send_from_directory('/Users/neog/static', filename)
   320→
   321→@app.route('/api/log', methods=['POST'])
   322→def receive_log():
   323→    """Receive log entry from client"""
   324→    try:
   325→        log_data = request.json
   326→
   327→        # Extract client info
   328→        device_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
   329→        user_agent = request.headers.get('User-Agent', 'Unknown')
   330→
   331→        # Insert into database
   332→        conn = sqlite3.connect(DB_PATH)
   333→        c = conn.cursor()
   334→        c.execute('''INSERT INTO logs
   335→                     (timestamp, level, source, message, data, device_ip, user_agent, url)
   336→                     VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
   337→                  (log_data.get('timestamp', datetime.utcnow().isoformat()),
   338→                   log_data.get('level', 'info'),
   339→                   log_data.get('source', 'UNKNOWN'),
   340→                   log_data.get('message', ''),
   341→                   json.dumps(log_data.get('data', {})),
   342→                   device_ip,
   343→                   user_agent,
   344→                   log_data.get('url', '')))
   345→
   346→        log_id = c.lastrowid
   347→        conn.commit()
   348→        conn.close()
   349→

<system-reminder>
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.
</system-reminder>

session_id TEXT,
        prompt TEXT NOT NULL,
        source TEXT DEFAULT 'manual',
        device_ip TEXT,
        status TEXT DEFAULT 'pending',

        input_tokens INTEGER DEFAULT 0,
        output_tokens INTEGER DEFAULT 0,
        cache_read_tokens INTEGER DEFAULT 0,
        model TEXT DEFAULT 'claude-opus-4-5-20251101',

        cost_usd REAL DEFAULT 0,
        value_generated_usd REAL DEFAULT 0,

        gate_guardrails_ok BOOLEAN DEFAULT 1,
        gate_budget_ok BOOLEAN DEFAULT 1,
        gate_heartbeat_ok BOOLEAN DEFAULT 1,
        halt_reason TEXT,

        started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        completed_at DATETIME,
        duration_ms INTEGER,

        tools_used TEXT,
        files_modified TEXT,
        error_message TEXT,
        tags TEXT
    )''')

    # cc_tags: Predefined tags for categorization
    c.execute('''CREATE TABLE IF NOT EXISTS cc_tags (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT UNIQUE NOT NULL,
        color TEXT DEFAULT '#00d4ff',
        description TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
    )''')

    # Seed default tags
    default_tags = [
        ('feature', '#10b981', 'New feature development'),
        ('bugfix', '#ef4444', 'Bug fixes'),
        ('refactor', '#f59e0b', 'Code refactoring'),
        ('docs', '#6366f1', 'Documentation'),
        ('test', '#8b5cf6', 'Testing'),
        ('devops', '#ec4899', 'DevOps and infrastructure'),
        ('research', '#14b8a6', 'Research and exploration')
    ]
    for tag_name, color, desc in default_tags:
        c.execute('INSERT OR IGNORE INTO cc_tags (name, color, description) VALUES (?, ?, ?)',
                  (tag_name, color, desc))

    # cc_events: Granular events within each run (feedback loop)
    c.execute('''CREATE TABLE IF NOT EXISTS cc_events (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        run_id TEXT NOT NULL,
        event_type TEXT NOT NULL,
        event_subtype TEXT,

        input_tokens INTEGER DEFAULT 0,
        output_tokens INTEGER DEFAULT 0,
        cost_usd REAL DEFAULT 0,

        input_data TEXT,
        output_data TEXT,
        duration_ms INTEGER,
        success BOOLEAN DEFAULT 1,

        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (run_id) REFERENCES cc_runs(run_id)
    )''')

    # budget_config: 3-Gate budget limits
    c.execute('''CREATE TABLE IF NOT EXISTS budget_config (
        id INTEGER PRIMARY KEY,
        name TEXT UNIQUE NOT NULL,
        daily_limit_usd REAL DEFAULT 10.00,
        monthly_limit_usd REAL DEFAULT 200.00,
        max_tokens_per_run INTEGER DEFAULT 100000,
        max_cost_per_run_usd REAL DEFAULT 2.00,
        alert_threshold_pct INTEGER DEFAULT 80,
        is_active BOOLEAN DEFAULT 1,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
    )''')

    # guardrails: Safety rules
    c.execute('''CREATE TABLE IF NOT EXISTS guardrails (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        rule_type TEXT NOT NULL,
        pattern TEXT NOT NULL,
        action TEXT DEFAULT 'block',
        is_active BOOLEAN DEFAULT 1,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
    )''')

    # CC indexes
    c.execute('CREATE INDEX IF NOT EXISTS idx_cc_runs_status ON cc_runs(status)')
    c.execute('CREATE INDEX IF NOT EXISTS idx_cc_runs_started ON cc_runs(started_at)')
    c.execute('CREATE INDEX IF NOT EXISTS idx_cc_events_run ON cc_events(run_id)')
    c.execute('CREATE INDEX IF NOT EXISTS idx_cc_events_type ON cc_events(event_type)')

    # Seed default budget config
    c.execute('''INSERT OR IGNORE INTO budget_config (id, name, daily_limit_usd, monthly_limit_usd)
                 VALUES (1, 'default', 10.00, 200.00)''')

    # Seed default guardrails
    guardrails_seed = [
        ('block_rm_rf', 'blocked_command', 'rm -rf /', 'block'),
        ('block_rm_rf_home', 'blocked_command', 'rm -rf ~', 'block'),
        ('block_sudo', 'blocked_command', 'sudo', 'warn'),
        ('block_force_push', 'blocked_command', 'git push --force', 'warn'),
        ('block_force_push_main', 'blocked_command', 'git push -f origin main', 'block'),
        ('block_secrets', 'blocked_path', '**/*secret*', 'block'),
        ('block_env', 'blocked_path', '.env', 'warn'),
        ('block_ssh', 'blocked_path', '.ssh', 'block'),
    ]
    for name, rule_type, pattern, action in guardrails_seed:
        c.execute('''INSERT OR IGNORE INTO guardrails (name, rule_type, pattern, action)
                     VALUES (?, ?, ?, ?)''', (name, rule_type, pattern, action))

    conn.commit()
    conn.close()
    print(f"✓ Database initialized at {DB_PATH}")
    print(f"✓ CC tracking tables ready (cc_runs, cc_events, budget_config, guardrails)")

@app.route('/')
def index():
    """Redirect to live dashboard"""
    return '''

        <title>NEOG Log Server</title>

🔍 NEOG OS - Log Server

Server is running on port 9001

📊 Automation ROI Dashboard (NEW)

Live Dashboard

Metrics Dashboard (PWA)

Statistics (JSON)

Recent Logs (JSON)

📈 CC Tracking API

System Status

Gate Health

ROI Summary

Recent Runs

Budget Status

Guardrails

    '''

@app.route('/dashboard')
def dashboard():
    """Serve live dashboard"""
    return send_from_directory('/Users/neog', 'neog-logs-live.html')

@app.route('/metrics')
def metrics():
    """Serve advanced metrics dashboard (PWA)"""
    return send_from_directory('/Users/neog', 'neog-metrics.html')

# Serve PWA static files
@app.route('/static/<path:filename>')
def serve_static(filename):
    """Serve static files (PWA assets)"""
    return send_from_directory('/Users/neog/static', filename)

@app.route('/api/log', methods=['POST'])
def receive_log():
    """Receive log entry from client"""
    try:
        log_data = request.json

        # Extract client info
        device_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
        user_agent = request.headers.get('User-Agent', 'Unknown')

        # Insert into database
        conn = sqlite3.connect(DB_PATH)
        c = conn.cursor()
        c.execute('''INSERT INTO logs
                     (timestamp, level, source, message, data, device_ip, user_agent, url)
                     VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
                  (log_data.get('timestamp', datetime.utcnow().isoformat()),
                   log_data.get('level', 'info'),
                   log_data.get('source', 'UNKNOWN'),
                   log_data.get('message', ''),
                   json.dumps(log_data.get('data', {})),
                   device_ip,
                   user_agent,
                   log_data.get('url', '')))

        log_id = c.lastrowid
        conn.commit()
        conn.close()


29:def send_macos_notification(title, message, subtitle=None, sound='default'):
42:def send_webhook_notification(title, message, level='info'):
89:def send_alert(title, message, level='info', subtitle=None):
121:def init_db():
198:    for tag_name, color, desc in default_tags:
277:def index():
306:def dashboard():
311:def metrics():
317:def serve_static(filename):
322:def receive_log():
364:def get_logs():
414:def get_stats():
451:def get_devices():
474:def clear_logs():
489:def handle_connect():
495:def handle_disconnect():
500:def handle_request_logs(data):
524:def create_page():
560:def serve_page(filename):
568:def list_pages():
597:def classify_text():
663:    'default': {'input': 3.00, 'output': 15.00, 'cache_read': 0.30}
666:def calculate_cost(input_tokens, output_tokens, cache_read_tokens=0, model='default'):
681:def create_cc_run():
716:def update_cc_run(run_id):
768:def estimate_run_value(prompt, source, cost_usd, tokens):
811:def complete_cc_run(run_id):
907:def update_run_value(run_id):
950:def clear_estimates():
975:def get_cc_runs():


Perfect! Let me get more endpoint information:


grep -n "@app.route\|@socketio" /Users/neog/Services/servers/log-server.py | head -50

Find all Flask endpoints in log-server


grep -n "@app.route\|@socketio" /Users/neog/Services/servers/system-monitor-server.py

Find all Flask endpoints in system-monitor-server


244:@app.route('/api/system/all', methods=['GET'])
260:@app.route('/api/system/cpu', methods=['GET'])
264:@app.route('/api/system/gpu', methods=['GET'])
268:@app.route('/api/system/memory', methods=['GET'])
272:@app.route('/api/system/disk', methods=['GET'])
276:@app.route('/api/system/temperature', methods=['GET'])
280:@app.route('/api/system/battery', methods=['GET'])
284:@app.route('/api/system/network', methods=['GET'])
288:@app.route('/api/system/processes', methods=['GET'])
292:@app.route('/api/health', methods=['GET'])
296:@app.route('/', methods=['GET'])


276:@app.route('/')
305:@app.route('/dashboard')
310:@app.route('/metrics')
316:@app.route('/static/<path:filename>')
321:@app.route('/api/log', methods=['POST'])
363:@app.route('/api/logs', methods=['GET'])
413:@app.route('/api/stats', methods=['GET'])
450:@app.route('/api/devices', methods=['GET'])
473:@app.route('/api/clear', methods=['POST'])
488:@socketio.on('connect')
494:@socketio.on('disconnect')
499:@socketio.on('request_logs')
523:@app.route('/api/create-page', methods=['POST'])
559:@app.route('/page/<filename>')
567:@app.route('/api/list-pages', methods=['GET'])
596:@app.route('/api/classify-text', methods=['POST'])
680:@app.route('/api/cc/run', methods=['POST'])
715:@app.route('/api/cc/run/<run_id>', methods=['PATCH'])
810:@app.route('/api/cc/run/<run_id>/complete', methods=['POST'])
906:@app.route('/api/cc/run/<run_id>/value', methods=['POST'])
949:@app.route('/api/cc/runs/clear-estimates', methods=['POST'])
974:@app.route('/api/cc/runs', methods=['GET'])
1029:@app.route('/api/cc/run/<run_id>', methods=['GET'])
1067:@app.route('/api/cc/roi/real', methods=['GET'])
1128:@app.route('/api/cc/event', methods=['POST'])
1186:@app.route('/api/cc/events', methods=['GET'])
1222:@app.route('/api/cc/roi/summary', methods=['GET'])
1282:@app.route('/api/cc/roi/all-time', methods=['GET'])
1358:@app.route('/api/cc/roi/daily', methods=['GET'])
1387:@app.route('/api/cc/roi/by-source', methods=['GET'])
1413:@app.route('/api/cc/insights', methods=['GET'])
1554:@app.route('/api/cc/budget/auto-scale', methods=['POST'])
1612:@app.route('/api/cc/achievements', methods=['GET'])
1694:@app.route('/api/cc/forecast', methods=['GET'])
1776:@app.route('/api/cc/export', methods=['GET'])
1837:@app.route('/api/cc/export/csv', methods=['GET'])
1869:@app.route('/api/cc/gate/check', methods=['POST'])
1945:@app.route('/api/cc/gate/heartbeat', methods=['POST'])
1975:@app.route('/api/cc/budget', methods=['GET'])
2009:@app.route('/api/cc/budget', methods=['POST'])
2040:@app.route('/api/cc/guardrails', methods=['GET'])
2057:@app.route('/api/cc/tags', methods=['GET'])
2071:@app.route('/api/cc/tags', methods=['POST'])
2087:@app.route('/api/cc/run/<run_id>/tags', methods=['POST'])
2105:@app.route('/api/cc/runs/by-tag/<tag>', methods=['GET'])
2132:@app.route('/api/cc/roi/by-tag', methods=['GET'])
2167:@app.route('/api/cc/guardrails', methods=['POST'])
2197:@app.route('/api/cc/export/runs', methods=['GET'])
2240:@app.route('/api/cc/webhooks', methods=['GET'])
2249:@app.route('/api/cc/webhooks', methods=['POST'])


Excellent! Now let me get more details on the workspace API and check the Apps state:


grep -n "@app.route\|@socketio" /Users/neog/Services/servers/workspace-manager-api.py | head -20

Find workspace API endpoints


     1→import SwiftUI
     2→import Combine
     3→
     4→@MainActor
     5→final class AppState: ObservableObject {
     6→    // MARK: - Navigation
     7→    @Published var selectedCategory: SidebarCategory = .dashboard
     8→    @Published var isSearchPresented: Bool = false
     9→    @Published var selectedRunId: String?
    10→
    11→    // MARK: - CC ROI Data
    12→    @Published var roiSummary: ROISummary?
    13→    @Published var allTimeStats: AllTimeStats?
    14→    @Published var recentRuns: [CCRun] = []
    15→    @Published var budgetConfig: BudgetConfig?
    16→
    17→    // MARK: - Services
    18→    @Published var services: [ServiceStatus] = []
    19→
    20→    // MARK: - Connection Status
    21→    @Published var isConnected: Bool = false
    22→    @Published var lastSyncDate: Date?
    23→    @Published var syncError: String?
    24→    @Published var connectionState: RealtimeService.ConnectionState = .disconnected
    25→    private var previousConnectionState: Bool = false
    26→
    27→    // MARK: - Alerts
    28→    @Published var currentAlert: BudgetAlert?
    29→    @Published var showBudgetAlert: Bool = false
    30→
    31→    // MARK: - Export Triggers
    32→    @Published var triggerExportJSON: Bool = false
    33→    @Published var triggerExportCSV: Bool = false
    34→    @Published var triggerExportSummary: Bool = false
    35→
    36→    // MARK: - Services
    37→    private let apiClient = APIClient.shared
    38→    private let ccService = CCTrackingService()
    39→    private let realtimeService = RealtimeService.shared
    40→    private let notificationService = NotificationService.shared
    41→    private var refreshTask: Task<Void, Never>?
    42→    private var cancellables = Set<AnyCancellable>()
    43→    private var notificationObservers: [NSObjectProtocol] = []
    44→
    45→    init() {
    46→        setupRealtimeSubscriptions()
    47→        setupNotificationObservers()
    48→        realtimeService.start()
    49→
    50→        // Request notification authorization on first launch
    51→        Task {
    52→            await notificationService.checkAuthorizationStatus()
    53→        }
    54→    }
    55→
    56→    deinit {
    57→        refreshTask?.cancel()
    58→        notificationObservers.forEach { NotificationCenter.default.removeObserver($0) }
    59→    }
    60→
    61→    // MARK: - Notification Observers
    62→
    63→    private func setupNotificationObservers() {
    64→        // Navigate to Monitoring
    65→        let monitoringObserver = NotificationCenter.default.addObserver(
    66→            forName: .navigateToMonitoring,
    67→            object: nil,
    68→            queue: .main
    69→        ) { [weak self] _ in
    70→            Task { @MainActor in
    71→                self?.selectedCategory = .monitoring
    72→            }
    73→        }
    74→        notificationObservers.append(monitoringObserver)
    75→
    76→        // Navigate to Services
    77→        let servicesObserver = NotificationCenter.default.addObserver(
    78→            forName: .navigateToServices,
    79→            object: nil,
    80→            queue: .main
    81→        ) { [weak self] _ in
    82→            Task { @MainActor in
    83→                self?.selectedCategory = .services
    84→            }
    85→        }
    86→        notificationObservers.append(servicesObserver)
    87→
    88→        // Navigate to specific run
    89→        let runObserver = NotificationCenter.default.addObserver(
    90→            forName: .navigateToRun,
    91→            object: nil,
    92→            queue: .main
    93→        ) { [weak self] notification in
    94→            Task { @MainActor in
    95→                if let runId = notification.object as? String {
    96→                    self?.selectedCategory = .monitoring
    97→                    self?.selectedRunId = runId
    98→                }
    99→            }
   100→        }
   101→        notificationObservers.append(runObserver)
   102→
   103→        // Start service from notification
   104→        let startServiceObserver = NotificationCenter.default.addObserver(
   105→            forName: .startService,
   106→            object: nil,
   107→            queue: .main
   108→        ) { [weak self] notification in
   109→            Task { @MainActor in
   110→                if let serviceName = notification.object as? String {
   111→                    await self?.handleStartService(serviceName)
   112→                }
   113→            }
   114→        }
   115→        notificationObservers.append(startServiceObserver)
   116→
   117→        // Stop service from notification
   118→        let stopServiceObserver = NotificationCenter.default.addObserver(
   119→            forName: .stopService,
   120→            object: nil,
   121→            queue: .main
   122→        ) { [weak self] notification in
   123→            Task { @MainActor in
   124→                if let serviceName = notification.object as? String {
   125→                    await self?.handleStopService(serviceName)
   126→                }
   127→            }
   128→        }
   129→        notificationObservers.append(stopServiceObserver)
   130→    }
   131→
   132→    private func handleStartService(_ serviceName: String) async {
   133→        let serviceManager = ServiceManager.shared
   134→        if let definition = ServiceManager.serviceDefinitions.first(where: { $0.name == serviceName }) {
   135→            _ = await serviceManager.startService(definition)
   136→            await refreshServices()
   137→        }
   138→    }
   139→
   140→    private func handleStopService(_ serviceName: String) async {
   141→        let serviceManager = ServiceManager.shared
   142→        if let definition = ServiceManager.serviceDefinitions.first(where: { $0.name == serviceName }) {
   143→            _ = await serviceManager.stopService(definition)
   144→            await refreshServices()
   145→        }
   146→    }
   147→
   148→    // MARK: - Realtime Subscriptions
   149→
   150→    private func setupRealtimeSubscriptions() {

<system-reminder>
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.
</system-reminder>

import SwiftUI
import Combine

@MainActor
final class AppState: ObservableObject {
    // MARK: - Navigation
    @Published var selectedCategory: SidebarCategory = .dashboard
    @Published var isSearchPresented: Bool = false
    @Published var selectedRunId: String?

    // MARK: - CC ROI Data
    @Published var roiSummary: ROISummary?
    @Published var allTimeStats: AllTimeStats?
    @Published var recentRuns: [CCRun] = []
    @Published var budgetConfig: BudgetConfig?

    // MARK: - Services
    @Published var services: [ServiceStatus] = []

    // MARK: - Connection Status
    @Published var isConnected: Bool = false
    @Published var lastSyncDate: Date?
    @Published var syncError: String?
    @Published var connectionState: RealtimeService.ConnectionState = .disconnected
    private var previousConnectionState: Bool = false

    // MARK: - Alerts
    @Published var currentAlert: BudgetAlert?
    @Published var showBudgetAlert: Bool = false

    // MARK: - Export Triggers
    @Published var triggerExportJSON: Bool = false
    @Published var triggerExportCSV: Bool = false
    @Published var triggerExportSummary: Bool = false

    // MARK: - Services
    private let apiClient = APIClient.shared
    private let ccService = CCTrackingService()
    private let realtimeService = RealtimeService.shared
    private let notificationService = NotificationService.shared
    private var refreshTask: Task<Void, Never>?
    private var cancellables = Set<AnyCancellable>()
    private var notificationObservers: [NSObjectProtocol] = []

    init() {
        setupRealtimeSubscriptions()
        setupNotificationObservers()
        realtimeService.start()

        // Request notification authorization on first launch
        Task {
            await notificationService.checkAuthorizationStatus()
        }
    }

    deinit {
        refreshTask?.cancel()
        notificationObservers.forEach { NotificationCenter.default.removeObserver($0) }
    }

    // MARK: - Notification Observers

    private func setupNotificationObservers() {
        // Navigate to Monitoring
        let monitoringObserver = NotificationCenter.default.addObserver(
            forName: .navigateToMonitoring,
            object: nil,
            queue: .main
        ) { [weak self] _ in
            Task { @MainActor in
                self?.selectedCategory = .monitoring
            }
        }
        notificationObservers.append(monitoringObserver)

        // Navigate to Services
        let servicesObserver = NotificationCenter.default.addObserver(
            forName: .navigateToServices,
            object: nil,
            queue: .main
        ) { [weak self] _ in
            Task { @MainActor in
                self?.selectedCategory = .services
            }
        }
        notificationObservers.append(servicesObserver)

        // Navigate to specific run
        let runObserver = NotificationCenter.default.addObserver(
            forName: .navigateToRun,
            object: nil,
            queue: .main
        ) { [weak self] notification in
            Task { @MainActor in
                if let runId = notification.object as? String {
                    self?.selectedCategory = .monitoring
                    self?.selectedRunId = runId
                }
            }
        }
        notificationObservers.append(runObserver)

        // Start service from notification
        let startServiceObserver = NotificationCenter.default.addObserver(
            forName: .startService,
            object: nil,
            queue: .main
        ) { [weak self] notification in
            Task { @MainActor in
                if let serviceName = notification.object as? String {
                    await self?.handleStartService(serviceName)
                }
            }
        }
        notificationObservers.append(startServiceObserver)

        // Stop service from notification
        let stopServiceObserver = NotificationCenter.default.addObserver(
            forName: .stopService,
            object: nil,
            queue: .main
        ) { [weak self] notification in
            Task { @MainActor in
                if let serviceName = notification.object as? String {
                    await self?.handleStopService(serviceName)
                }
            }
        }
        notificationObservers.append(stopServiceObserver)
    }

    private func handleStartService(_ serviceName: String) async {
        let serviceManager = ServiceManager.shared
        if let definition = ServiceManager.serviceDefinitions.first(where: { $0.name == serviceName }) {
            _ = await serviceManager.startService(definition)
            await refreshServices()
        }
    }

    private func handleStopService(_ serviceName: String) async {
        let serviceManager = ServiceManager.shared
        if let definition = ServiceManager.serviceDefinitions.first(where: { $0.name == serviceName }) {
            _ = await serviceManager.stopService(definition)
            await refreshServices()
        }
    }

    // MARK: - Realtime Subscriptions

    private func setupRealtimeSubscriptions() {