// AUTO-GENERATED by scripts/generate-command-builders.mjs — DO NOT EDIT.
// Source of truth: shared/src/protocol.ts (PluginCommand union).
//
// Purpose: compile-time-safe construction of commands the Swift daemon
// sends to session bridges. Prevents field-name typos (e.g. `response`
// vs `value`) because each variant is a distinct enum case.

import Foundation

public enum AgentCommand: Equatable {
    case respond(value: String)
    case selectOption(index: Int, sessionId: String?)
    case navigateOption(direction: String)
    case sendPrompt(text: String)
    case switchMode(mode: String?)
    case interrupt
    case escape
    case voice(action: String)
    case queryUsage
    case querySessionTimeline(sessionId: String)
    case diag(action: String)
    case utility(action: String, value: Int?)
    case switchAgent(agent: String)
    case focusSession(sessionId: String)
    case clearSessionFocus
    case sessionCommand(sessionId: String, command: [String: Any])
    case clientRegister(clientType: String, clientLabel: String?, devices: [[String: Any]]?)
    case apmeVibe(runId: String, verdict: String, note: String?)
    case apmeRecommend(taskKind: String?, budgetUsd: Int?, latencyBudgetMs: Int?, preferLocal: Bool?)
    case permissionDecision(requestId: String, decision: String)
    case esp32OtaAck(otaId: String, stage: String, seq: Int?, offset: Int?, written: Int?)
    case esp32OtaError(error: String, otaId: String?, stage: String?)

    /// JSON-serializable dictionary representation matching protocol.ts.
    public var dictionary: [String: Any] {
        switch self {
        case .respond(let value):
            var dict: [String: Any] = ["type": "respond"]
            dict["value"] = value
            return dict
        case .selectOption(let index, let sessionId):
            var dict: [String: Any] = ["type": "select_option"]
            dict["index"] = index
            if let sessionId = sessionId { dict["sessionId"] = sessionId }
            return dict
        case .navigateOption(let direction):
            var dict: [String: Any] = ["type": "navigate_option"]
            dict["direction"] = direction
            return dict
        case .sendPrompt(let text):
            var dict: [String: Any] = ["type": "send_prompt"]
            dict["text"] = text
            return dict
        case .switchMode(let mode):
            var dict: [String: Any] = ["type": "switch_mode"]
            if let mode = mode { dict["mode"] = mode }
            return dict
        case .interrupt:
            return ["type": "interrupt"]
        case .escape:
            return ["type": "escape"]
        case .voice(let action):
            var dict: [String: Any] = ["type": "voice"]
            dict["action"] = action
            return dict
        case .queryUsage:
            return ["type": "query_usage"]
        case .querySessionTimeline(let sessionId):
            var dict: [String: Any] = ["type": "query_session_timeline"]
            dict["sessionId"] = sessionId
            return dict
        case .diag(let action):
            var dict: [String: Any] = ["type": "diag"]
            dict["action"] = action
            return dict
        case .utility(let action, let value):
            var dict: [String: Any] = ["type": "utility"]
            dict["action"] = action
            if let value = value { dict["value"] = value }
            return dict
        case .switchAgent(let agent):
            var dict: [String: Any] = ["type": "switch_agent"]
            dict["agent"] = agent
            return dict
        case .focusSession(let sessionId):
            var dict: [String: Any] = ["type": "focus_session"]
            dict["sessionId"] = sessionId
            return dict
        case .clearSessionFocus:
            return ["type": "clear_session_focus"]
        case .sessionCommand(let sessionId, let command):
            var dict: [String: Any] = ["type": "session_command"]
            dict["sessionId"] = sessionId
            dict["command"] = command
            return dict
        case .clientRegister(let clientType, let clientLabel, let devices):
            var dict: [String: Any] = ["type": "client_register"]
            dict["clientType"] = clientType
            if let clientLabel = clientLabel { dict["clientLabel"] = clientLabel }
            if let devices = devices { dict["devices"] = devices }
            return dict
        case .apmeVibe(let runId, let verdict, let note):
            var dict: [String: Any] = ["type": "apme_vibe"]
            dict["runId"] = runId
            dict["verdict"] = verdict
            if let note = note { dict["note"] = note }
            return dict
        case .apmeRecommend(let taskKind, let budgetUsd, let latencyBudgetMs, let preferLocal):
            var dict: [String: Any] = ["type": "apme_recommend"]
            if let taskKind = taskKind { dict["taskKind"] = taskKind }
            if let budgetUsd = budgetUsd { dict["budgetUsd"] = budgetUsd }
            if let latencyBudgetMs = latencyBudgetMs { dict["latencyBudgetMs"] = latencyBudgetMs }
            if let preferLocal = preferLocal { dict["preferLocal"] = preferLocal }
            return dict
        case .permissionDecision(let requestId, let decision):
            var dict: [String: Any] = ["type": "permission_decision"]
            dict["requestId"] = requestId
            dict["decision"] = decision
            return dict
        case .esp32OtaAck(let otaId, let stage, let seq, let offset, let written):
            var dict: [String: Any] = ["type": "esp32_ota_ack"]
            dict["otaId"] = otaId
            dict["stage"] = stage
            if let seq = seq { dict["seq"] = seq }
            if let offset = offset { dict["offset"] = offset }
            if let written = written { dict["written"] = written }
            return dict
        case .esp32OtaError(let error, let otaId, let stage):
            var dict: [String: Any] = ["type": "esp32_ota_error"]
            dict["error"] = error
            if let otaId = otaId { dict["otaId"] = otaId }
            if let stage = stage { dict["stage"] = stage }
            return dict
        }
    }

    /// Discriminant tag as it appears over the wire.
    public var typeTag: String {
        switch self {
        case .respond: return "respond"
        case .selectOption: return "select_option"
        case .navigateOption: return "navigate_option"
        case .sendPrompt: return "send_prompt"
        case .switchMode: return "switch_mode"
        case .interrupt: return "interrupt"
        case .escape: return "escape"
        case .voice: return "voice"
        case .queryUsage: return "query_usage"
        case .querySessionTimeline: return "query_session_timeline"
        case .diag: return "diag"
        case .utility: return "utility"
        case .switchAgent: return "switch_agent"
        case .focusSession: return "focus_session"
        case .clearSessionFocus: return "clear_session_focus"
        case .sessionCommand: return "session_command"
        case .clientRegister: return "client_register"
        case .apmeVibe: return "apme_vibe"
        case .apmeRecommend: return "apme_recommend"
        case .permissionDecision: return "permission_decision"
        case .esp32OtaAck: return "esp32_ota_ack"
        case .esp32OtaError: return "esp32_ota_error"
        }
    }

    public static func == (lhs: AgentCommand, rhs: AgentCommand) -> Bool {
        return NSDictionary(dictionary: lhs.dictionary).isEqual(to: rhs.dictionary)
    }
}
