// AUTO-GENERATED by scripts/generate-command-builders.mjs — DO NOT EDIT.
// Source of truth: shared/src/protocol.ts (PluginCommand union).

package dev.agentdeck.generated

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.JsonNull

sealed class AgentCommand {
    abstract val typeTag: String
    abstract fun toJson(): String

    data class Respond(val value: String) : AgentCommand() {
        override val typeTag: String = "respond"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"respond\"")
            buf.append(",\"value\":").append(encode(value))
            buf.append("}")
            return buf.toString()
        }
    }

    data class SelectOption(val index: Int, val sessionId: String? = null) : AgentCommand() {
        override val typeTag: String = "select_option"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"select_option\"")
            buf.append(",\"index\":").append(encode(index))
            if (sessionId != null) buf.append(",\"sessionId\":").append(encode(sessionId))
            buf.append("}")
            return buf.toString()
        }
    }

    data class NavigateOption(val direction: String) : AgentCommand() {
        override val typeTag: String = "navigate_option"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"navigate_option\"")
            buf.append(",\"direction\":").append(encode(direction))
            buf.append("}")
            return buf.toString()
        }
    }

    data class SendPrompt(val text: String) : AgentCommand() {
        override val typeTag: String = "send_prompt"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"send_prompt\"")
            buf.append(",\"text\":").append(encode(text))
            buf.append("}")
            return buf.toString()
        }
    }

    data class SwitchMode(val mode: String? = null) : AgentCommand() {
        override val typeTag: String = "switch_mode"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"switch_mode\"")
            if (mode != null) buf.append(",\"mode\":").append(encode(mode))
            buf.append("}")
            return buf.toString()
        }
    }

    object Interrupt : AgentCommand() {
        override val typeTag: String = "interrupt"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"interrupt\"")
            buf.append("}")
            return buf.toString()
        }
    }

    object Escape : AgentCommand() {
        override val typeTag: String = "escape"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"escape\"")
            buf.append("}")
            return buf.toString()
        }
    }

    data class Voice(val action: String) : AgentCommand() {
        override val typeTag: String = "voice"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"voice\"")
            buf.append(",\"action\":").append(encode(action))
            buf.append("}")
            return buf.toString()
        }
    }

    object QueryUsage : AgentCommand() {
        override val typeTag: String = "query_usage"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"query_usage\"")
            buf.append("}")
            return buf.toString()
        }
    }

    data class QuerySessionTimeline(val sessionId: String) : AgentCommand() {
        override val typeTag: String = "query_session_timeline"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"query_session_timeline\"")
            buf.append(",\"sessionId\":").append(encode(sessionId))
            buf.append("}")
            return buf.toString()
        }
    }

    data class Diag(val action: String) : AgentCommand() {
        override val typeTag: String = "diag"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"diag\"")
            buf.append(",\"action\":").append(encode(action))
            buf.append("}")
            return buf.toString()
        }
    }

    data class Utility(val action: String, val value: Int? = null) : AgentCommand() {
        override val typeTag: String = "utility"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"utility\"")
            buf.append(",\"action\":").append(encode(action))
            if (value != null) buf.append(",\"value\":").append(encode(value))
            buf.append("}")
            return buf.toString()
        }
    }

    data class SwitchAgent(val agent: String) : AgentCommand() {
        override val typeTag: String = "switch_agent"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"switch_agent\"")
            buf.append(",\"agent\":").append(encode(agent))
            buf.append("}")
            return buf.toString()
        }
    }

    data class FocusSession(val sessionId: String) : AgentCommand() {
        override val typeTag: String = "focus_session"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"focus_session\"")
            buf.append(",\"sessionId\":").append(encode(sessionId))
            buf.append("}")
            return buf.toString()
        }
    }

    object ClearSessionFocus : AgentCommand() {
        override val typeTag: String = "clear_session_focus"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"clear_session_focus\"")
            buf.append("}")
            return buf.toString()
        }
    }

    data class SessionCommand(val sessionId: String, val command: Map<String, Any?>) : AgentCommand() {
        override val typeTag: String = "session_command"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"session_command\"")
            buf.append(",\"sessionId\":").append(encode(sessionId))
            buf.append(",\"command\":").append(encode(command))
            buf.append("}")
            return buf.toString()
        }
    }

    data class ClientRegister(val clientType: String, val clientLabel: String? = null, val devices: List<Map<String, Any?>>? = null) : AgentCommand() {
        override val typeTag: String = "client_register"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"client_register\"")
            buf.append(",\"clientType\":").append(encode(clientType))
            if (clientLabel != null) buf.append(",\"clientLabel\":").append(encode(clientLabel))
            if (devices != null) buf.append(",\"devices\":").append(encode(devices))
            buf.append("}")
            return buf.toString()
        }
    }

    data class ApmeVibe(val runId: String, val verdict: String, val note: String? = null) : AgentCommand() {
        override val typeTag: String = "apme_vibe"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"apme_vibe\"")
            buf.append(",\"runId\":").append(encode(runId))
            buf.append(",\"verdict\":").append(encode(verdict))
            if (note != null) buf.append(",\"note\":").append(encode(note))
            buf.append("}")
            return buf.toString()
        }
    }

    data class ApmeRecommend(val taskKind: String? = null, val budgetUsd: Int? = null, val latencyBudgetMs: Int? = null, val preferLocal: Boolean? = null) : AgentCommand() {
        override val typeTag: String = "apme_recommend"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"apme_recommend\"")
            if (taskKind != null) buf.append(",\"taskKind\":").append(encode(taskKind))
            if (budgetUsd != null) buf.append(",\"budgetUsd\":").append(encode(budgetUsd))
            if (latencyBudgetMs != null) buf.append(",\"latencyBudgetMs\":").append(encode(latencyBudgetMs))
            if (preferLocal != null) buf.append(",\"preferLocal\":").append(encode(preferLocal))
            buf.append("}")
            return buf.toString()
        }
    }

    data class PermissionDecision(val requestId: String, val decision: String) : AgentCommand() {
        override val typeTag: String = "permission_decision"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"permission_decision\"")
            buf.append(",\"requestId\":").append(encode(requestId))
            buf.append(",\"decision\":").append(encode(decision))
            buf.append("}")
            return buf.toString()
        }
    }

    data class Esp32OtaAck(val otaId: String, val stage: String, val seq: Int? = null, val offset: Int? = null, val written: Int? = null) : AgentCommand() {
        override val typeTag: String = "esp32_ota_ack"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"esp32_ota_ack\"")
            buf.append(",\"otaId\":").append(encode(otaId))
            buf.append(",\"stage\":").append(encode(stage))
            if (seq != null) buf.append(",\"seq\":").append(encode(seq))
            if (offset != null) buf.append(",\"offset\":").append(encode(offset))
            if (written != null) buf.append(",\"written\":").append(encode(written))
            buf.append("}")
            return buf.toString()
        }
    }

    data class Esp32OtaError(val error: String, val otaId: String? = null, val stage: String? = null) : AgentCommand() {
        override val typeTag: String = "esp32_ota_error"
        override fun toJson(): String {
            val buf = StringBuilder()
            buf.append("{\"type\":\"esp32_ota_error\"")
            buf.append(",\"error\":").append(encode(error))
            if (otaId != null) buf.append(",\"otaId\":").append(encode(otaId))
            if (stage != null) buf.append(",\"stage\":").append(encode(stage))
            buf.append("}")
            return buf.toString()
        }
    }

    companion object {
        private val jsonFmt = Json { encodeDefaults = false }
        internal fun encode(v: Any?): String = when (v) {
            null -> "null"
            is String -> jsonFmt.encodeToString(kotlinx.serialization.serializer<String>(), v)
            is Number -> v.toString()
            is Boolean -> v.toString()
            is Map<*, *> -> {
                val parts = v.entries.joinToString(",") { (k, vv) ->
                    val keyJson = jsonFmt.encodeToString(kotlinx.serialization.serializer<String>(), k.toString())
                    keyJson + ":" + encode(vv)
                }
                "{" + parts + "}"
            }
            is Iterable<*> -> v.joinToString(prefix = "[", postfix = "]") { encode(it) }
            else -> jsonFmt.encodeToString(kotlinx.serialization.serializer<String>(), v.toString())
        }
    }
}
