{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://a.skh.am/pi-daemon/protocol.schema.json",
  "title": "Pi Daemon protocol v1",
  "description": "Language-neutral command, response, and event records for Pi Daemon's NDJSON protocol.",
  "oneOf": [
    { "$ref": "#/$defs/command" },
    { "$ref": "#/$defs/response" },
    { "$ref": "#/$defs/event" }
  ],
  "$defs": {
    "protocolVersion": {
      "type": "string",
      "pattern": "^1\\.[0-9]+$"
    },
    "identifier": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512
    },
    "baseCommand": {
      "type": "object",
      "required": ["protocolVersion", "requestId", "operation", "payload"],
      "properties": {
        "protocolVersion": { "$ref": "#/$defs/protocolVersion" },
        "requestId": { "$ref": "#/$defs/identifier" },
        "operation": { "type": "string" },
        "payload": { "type": "object" }
      }
    },
    "sessionIdentity": {
      "type": "object",
      "required": ["sessionId", "generation"],
      "properties": {
        "sessionId": { "$ref": "#/$defs/identifier" },
        "generation": { "type": "integer", "minimum": 0 }
      }
    },
    "idempotency": {
      "type": "object",
      "required": ["idempotencyKey"],
      "properties": {
        "idempotencyKey": { "$ref": "#/$defs/identifier" }
      }
    },
    "handshakeCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        {
          "type": "object",
          "properties": {
            "operation": { "const": "handshake" },
            "payload": { "type": "object" }
          }
        }
      ]
    },
    "modelPolicy": {
      "type": "object",
      "required": ["provider", "id"],
      "properties": {
        "provider": { "$ref": "#/$defs/identifier" },
        "id": { "$ref": "#/$defs/identifier" },
        "thinkingLevel": {
          "enum": ["off", "minimal", "low", "medium", "high", "xhigh", "max"]
        }
      }
    },
    "resourcePolicy": {
      "type": "object",
      "required": [
        "extensions",
        "skills",
        "promptTemplates",
        "themes",
        "contextFiles",
        "tools"
      ],
      "properties": {
        "extensions": { "const": "none" },
        "skills": { "const": "none" },
        "promptTemplates": { "const": "none" },
        "themes": { "const": "none" },
        "contextFiles": { "const": "none" },
        "tools": { "const": "none" },
        "systemPrompt": { "type": "string", "maxLength": 262144 }
      }
    },
    "openCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        { "$ref": "#/$defs/sessionIdentity" },
        {
          "type": "object",
          "properties": {
            "operation": { "const": "open" },
            "payload": {
              "type": "object",
              "required": ["cwd", "session"],
              "properties": {
                "cwd": { "type": "string", "minLength": 1, "maxLength": 4096 },
                "name": { "type": "string", "minLength": 1, "maxLength": 128 },
                "agentDir": { "type": "string", "minLength": 1, "maxLength": 4096 },
                "session": {
                  "type": "object",
                  "required": ["mode"],
                  "properties": {
                    "mode": { "enum": ["new", "open", "continue", "memory"] },
                    "path": { "type": "string", "minLength": 1, "maxLength": 4096 }
                  }
                },
                "model": { "$ref": "#/$defs/modelPolicy" },
                "resources": { "$ref": "#/$defs/resourcePolicy" }
              }
            }
          }
        }
      ]
    },
    "wakeCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        { "$ref": "#/$defs/sessionIdentity" },
        { "$ref": "#/$defs/idempotency" },
        {
          "type": "object",
          "properties": {
            "operation": { "const": "wake" },
            "payload": {
              "type": "object",
              "required": ["prompt"],
              "properties": {
                "prompt": { "type": "string", "minLength": 1, "maxLength": 262144 },
                "source": { "type": "string", "maxLength": 128 },
                "waitForTerminal": { "type": "boolean", "default": true }
              }
            }
          }
        }
      ]
    },
    "queuedMessageCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        { "$ref": "#/$defs/sessionIdentity" },
        { "$ref": "#/$defs/idempotency" },
        {
          "type": "object",
          "properties": {
            "operation": { "enum": ["steer", "followUp"] },
            "payload": {
              "type": "object",
              "required": ["message"],
              "properties": {
                "message": { "type": "string", "minLength": 1, "maxLength": 262144 }
              }
            }
          }
        }
      ]
    },
    "statusCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        {
          "type": "object",
          "properties": {
            "operation": { "const": "status" },
            "sessionId": { "$ref": "#/$defs/identifier" }
          }
        }
      ]
    },
    "abortCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        { "$ref": "#/$defs/sessionIdentity" },
        { "type": "object", "properties": { "operation": { "const": "abort" } } }
      ]
    },
    "attachCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        { "$ref": "#/$defs/sessionIdentity" },
        { "type": "object", "properties": { "operation": { "const": "attach" } } }
      ]
    },
    "detachCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        { "$ref": "#/$defs/sessionIdentity" },
        { "type": "object", "properties": { "operation": { "const": "detach" } } }
      ]
    },
    "closeCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        { "$ref": "#/$defs/sessionIdentity" },
        {
          "type": "object",
          "properties": {
            "operation": { "const": "close" },
            "payload": {
              "type": "object",
              "properties": { "retainSession": { "type": "boolean" } }
            }
          }
        }
      ]
    },
    "drainCommand": {
      "allOf": [
        { "$ref": "#/$defs/baseCommand" },
        {
          "type": "object",
          "properties": {
            "operation": { "const": "drain" },
            "payload": {
              "type": "object",
              "properties": {
                "timeoutMs": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 86400000
                }
              }
            }
          }
        }
      ]
    },
    "command": {
      "oneOf": [
        { "$ref": "#/$defs/handshakeCommand" },
        { "$ref": "#/$defs/openCommand" },
        { "$ref": "#/$defs/wakeCommand" },
        { "$ref": "#/$defs/queuedMessageCommand" },
        { "$ref": "#/$defs/statusCommand" },
        { "$ref": "#/$defs/abortCommand" },
        { "$ref": "#/$defs/attachCommand" },
        { "$ref": "#/$defs/detachCommand" },
        { "$ref": "#/$defs/closeCommand" },
        { "$ref": "#/$defs/drainCommand" }
      ]
    },
    "error": {
      "type": "object",
      "required": ["code", "message", "retryable"],
      "properties": {
        "code": { "type": "string" },
        "message": { "type": "string" },
        "retryable": { "type": "boolean" },
        "details": { "type": "object" }
      }
    },
    "response": {
      "type": "object",
      "required": ["protocolVersion", "kind", "requestId", "hostInstanceId", "ok"],
      "properties": {
        "protocolVersion": { "$ref": "#/$defs/protocolVersion" },
        "kind": { "const": "response" },
        "requestId": { "$ref": "#/$defs/identifier" },
        "hostInstanceId": { "$ref": "#/$defs/identifier" },
        "sessionId": { "$ref": "#/$defs/identifier" },
        "sequence": { "type": "integer", "minimum": 0 },
        "ok": { "type": "boolean" },
        "data": {},
        "error": { "$ref": "#/$defs/error" }
      }
    },
    "event": {
      "type": "object",
      "required": [
        "protocolVersion",
        "kind",
        "event",
        "hostInstanceId",
        "sessionId",
        "generation",
        "sequence"
      ],
      "properties": {
        "protocolVersion": { "$ref": "#/$defs/protocolVersion" },
        "kind": { "const": "event" },
        "event": { "type": "string" },
        "hostInstanceId": { "$ref": "#/$defs/identifier" },
        "sessionId": { "$ref": "#/$defs/identifier" },
        "generation": { "type": "integer", "minimum": 0 },
        "sequence": { "type": "integer", "minimum": 0 },
        "requestId": { "$ref": "#/$defs/identifier" },
        "data": {}
      }
    }
  }
}
