{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://registry.alineo.tech/spec/agent.json",
  "title": "AgentSpec",
  "description": "JSON spec for an alineo agent, fetched by `alineo add` and run by `alineo`'s Alineo.start(). See https://docs.alineo.tech/docs/cli/registry/schema for the full field reference.",
  "type": "object",
  "required": ["name", "harness"],
  "properties": {
    "$schema": {
      "type": "string",
      "description": "Editor/tooling hint pointing back at this schema."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "Unique identifier. Used as the saved filename (<name>.json) and the sandbox session name."
    },
    "title": {
      "type": "string",
      "description": "Human-readable display name."
    },
    "description": {
      "type": "string",
      "description": "Shown by `alineo list`, falling back from `title` if unset."
    },
    "author": {
      "type": "string",
      "description": "Author name and optional URL."
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Tags for discovery. Informational only."
    },
    "harness": {
      "oneOf": [
        {
          "enum": ["pi", "claude-code", "codex"]
        },
        {
          "type": "object",
          "required": ["id"],
          "properties": {
            "id": {
              "enum": ["pi", "claude-code", "codex"]
            },
            "version": {
              "type": "string",
              "description": "npm version specifier for the harness package, e.g. \"1.2.3\", \"^1.2.0\", or a dist-tag like \"latest\"."
            }
          },
          "additionalProperties": false
        }
      ],
      "description": "Agent-loop driver to run inside the sandbox: \"pi\", \"claude-code\" (Claude Agent SDK) or \"codex\" (codex app-server). Write an object to pin a version: { \"id\": \"pi\", \"version\": \"1.2.3\" }."
    },
    "harnessVersion": {
      "type": "string",
      "description": "Deprecated: use harness.version. npm version specifier for the harness, e.g. \"1.2.3\", \"^1.2.0\", or a dist-tag like \"latest\"."
    },
    "provider": {
      "type": "string",
      "description": "Deprecated: use model.provider. AI provider passed to Pi via --provider. Omit for a direct Google API key (Pi's default)."
    },
    "model": {
      "oneOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "object",
          "required": ["id"],
          "properties": {
            "id": {
              "type": "string",
              "minLength": 1
            },
            "provider": {
              "type": "string",
              "description": "AI provider. For Pi, passed as --provider. claude-code runs on anthropic and codex on openai."
            }
          },
          "additionalProperties": false
        }
      ],
      "description": "Model ID passed to Pi via --model. Write an object to name the provider with the model: { \"provider\": \"nvidia\", \"id\": \"nemotron-3-super-120b-a12b\" }."
    },
    "packages": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "APT packages installed before the CLI starts. nodejs/nodejs_22 are silently ignored (base image is node:22)."
    },
    "env": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Environment variables available inside the sandbox. Values may reference host env vars: \"${MY_API_KEY}\"."
    },
    "resources": {
      "type": "object",
      "properties": {
        "cpu": {
          "type": "string"
        },
        "memory": {
          "type": "string"
        },
        "gpu": {
          "type": "string"
        }
      },
      "required": ["cpu", "memory"],
      "additionalProperties": false,
      "description": "Falls back to defaults.resources in alineo.config.json if omitted."
    },
    "metadata": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Not read anywhere in alineo; has no effect on the sandbox."
    },
    "registryDependencies": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "URLs of other agent specs. alineo add fetches and saves each one first, depth-first. No cycle detection."
    },
    "setup": {
      "type": "array",
      "description": "Steps run inside the sandbox after CLI install, before the checkpoint.",
      "items": {
        "type": "object",
        "required": ["name", "run"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable label shown in logs."
          },
          "run": {
            "type": "string",
            "description": "Shell command to run (bash)."
          },
          "cwd": {
            "type": "string",
            "description": "If set, the command runs as `cd <cwd> && <run>`."
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": true
}
