ai-dispatch 10.39.0

Multi-AI CLI team orchestrator
// Client-side XP and rank math — persisted locally, not from server.
// Exports: XPState, RankCalculator.

import Foundation

struct XPState: Sendable, Equatable {
    var xp: Int

    static let defaultXP = 4280

    init(xp: Int = defaultXP) {
        self.xp = xp
    }

    mutating func award(for state: MissionDisplayState, payloadXP: Int = 140) {
        switch state {
        case .done: xp += payloadXP
        case .fail: xp += 20
        default: break
        }
    }

    var rankIndex: Int { min(7, xp / 1000) }
    var rankLabel: String { RankCalculator.label(for: rankIndex) }
    var barProgress: Double { Double(xp % 1000) / 1000 }
}

enum RankCalculator {
    static let ranks = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII"]

    static func label(for index: Int) -> String {
        let clamped = min(max(index, 0), ranks.count - 1)
        return ranks[clamped]
    }
}